diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 6a17fe1dd08..6f6592b4a6b 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "microsoft.dotnet.darc": { - "version": "1.1.0-beta.25358.3", + "version": "1.1.0-beta.25366.1", "commands": [ "darc" ] diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 428c37a15dc..3e4e0b1bed1 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -10,9 +10,9 @@ https://github.com/dotnet/dotnet 67889d9d2f21a890ac29bcd175c0d1937a401781 - + https://github.com/dotnet/arcade-services - afa79da3b68fd0fe48d90ea7fcbffbf7789c6d7f + 3a31b413f81d10b329db1c91aef860a77d5f3ab9 diff --git a/src/efcore/eng/Version.Details.xml b/src/efcore/eng/Version.Details.xml index a88e269d18e..0090de09b77 100644 --- a/src/efcore/eng/Version.Details.xml +++ b/src/efcore/eng/Version.Details.xml @@ -1,80 +1,80 @@ - + - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b diff --git a/src/efcore/eng/Versions.props b/src/efcore/eng/Versions.props index e2a9f7d63f0..8d7ef6a18e8 100644 --- a/src/efcore/eng/Versions.props +++ b/src/efcore/eng/Versions.props @@ -16,24 +16,24 @@ False - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 - 10.0.0-beta.25364.102 + 10.0.0-beta.25365.101 17.14.8 diff --git a/src/efcore/global.json b/src/efcore/global.json index 7cb1bad5cb7..b7232466c10 100644 --- a/src/efcore/global.json +++ b/src/efcore/global.json @@ -18,7 +18,7 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25364.102", - "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25364.102" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25365.101", + "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25365.101" } } diff --git a/src/efcore/src/EFCore.Relational/EFExtensions.cs b/src/efcore/src/EFCore.Relational/EFExtensions.cs index c2677cb8706..c790c6256f2 100644 --- a/src/efcore/src/EFCore.Relational/EFExtensions.cs +++ b/src/efcore/src/EFCore.Relational/EFExtensions.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections; + namespace Microsoft.EntityFrameworkCore; /// @@ -25,10 +27,10 @@ public static class EFExtensions /// Within the context of an EF LINQ query, forces its argument to be inserted into the query as a multiple parameter expressions. /// /// Note that this is a static method accessed through the top-level static type. - /// The type of collection element. + /// The type of collection. /// The collection to be integrated as parameters into the query. /// The same value for further use in the query. - public static IEnumerable MultipleParameters(IEnumerable argument) + public static TSource MultipleParameters(TSource argument) where TSource : IEnumerable => throw new InvalidOperationException(RelationalStrings.EFMultipleParametersInvoked); } } diff --git a/src/efcore/src/EFCore.Relational/Infrastructure/RelationalDbContextOptionsBuilder.cs b/src/efcore/src/EFCore.Relational/Infrastructure/RelationalDbContextOptionsBuilder.cs index 269a68bfb0a..01935a24036 100644 --- a/src/efcore/src/EFCore.Relational/Infrastructure/RelationalDbContextOptionsBuilder.cs +++ b/src/efcore/src/EFCore.Relational/Infrastructure/RelationalDbContextOptionsBuilder.cs @@ -179,7 +179,7 @@ public virtual TBuilder ExecutionStrategy( /// [Obsolete("Use UseParameterizedCollectionMode instead.")] public virtual TBuilder TranslateParameterizedCollectionsToConstants() - => UseParameterizedCollectionMode(ParameterizedCollectionMode.Constants); + => UseParameterizedCollectionMode(ParameterTranslationMode.Constant); /// /// Configures the context to translate parameterized collections to a single array-like parameter. @@ -202,13 +202,13 @@ public virtual TBuilder TranslateParameterizedCollectionsToConstants() /// [Obsolete("Use UseParameterizedCollectionMode instead.")] public virtual TBuilder TranslateParameterizedCollectionsToParameters() - => UseParameterizedCollectionMode(ParameterizedCollectionMode.Parameter); + => UseParameterizedCollectionMode(ParameterTranslationMode.Parameter); /// - /// Configures the to use when translating parameterized collections. + /// Configures the mode to use when translating parameterized collections. /// /// The same builder instance so that multiple calls can be chained. - public virtual TBuilder UseParameterizedCollectionMode(ParameterizedCollectionMode parameterizedCollectionMode) + public virtual TBuilder UseParameterizedCollectionMode(ParameterTranslationMode parameterizedCollectionMode) => WithOption(e => (TExtension)e.WithUseParameterizedCollectionMode(parameterizedCollectionMode)); /// diff --git a/src/efcore/src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs b/src/efcore/src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs index e2cc09b80c8..a052b74c1eb 100644 --- a/src/efcore/src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs +++ b/src/efcore/src/EFCore.Relational/Infrastructure/RelationalOptionsExtension.cs @@ -36,7 +36,7 @@ public abstract class RelationalOptionsExtension : IDbContextOptionsExtension private string? _migrationsHistoryTableName; private string? _migrationsHistoryTableSchema; private Func? _executionStrategyFactory; - private ParameterizedCollectionMode? _parameterizedCollectionMode; + private ParameterTranslationMode? _parameterizedCollectionMode; /// /// Creates a new set of options with everything set to default values. @@ -386,8 +386,8 @@ public virtual RelationalOptionsExtension WithExecutionStrategyFactory( /// /// Configured translation mode for parameterized collections. /// - public virtual ParameterizedCollectionMode ParameterizedCollectionMode - => _parameterizedCollectionMode ?? ParameterizedCollectionMode.MultipleParameters; + public virtual ParameterTranslationMode ParameterizedCollectionMode + => _parameterizedCollectionMode ?? ParameterTranslationMode.MultipleParameters; /// /// Creates a new instance with all options the same as for this instance, but with the given option changed. @@ -395,7 +395,7 @@ public virtual ParameterizedCollectionMode ParameterizedCollectionMode /// /// The option to change. public virtual RelationalOptionsExtension WithUseParameterizedCollectionMode( - ParameterizedCollectionMode parameterizedCollectionMode) + ParameterTranslationMode parameterizedCollectionMode) { var clone = Clone(); diff --git a/src/efcore/src/EFCore.Relational/Query/Internal/RelationalCommandCache.cs b/src/efcore/src/EFCore.Relational/Query/Internal/RelationalCommandCache.cs index 4d19a2b3eaa..e7ba5c61764 100644 --- a/src/efcore/src/EFCore.Relational/Query/Internal/RelationalCommandCache.cs +++ b/src/efcore/src/EFCore.Relational/Query/Internal/RelationalCommandCache.cs @@ -35,13 +35,13 @@ public RelationalCommandCache( IRelationalParameterBasedSqlProcessorFactory relationalParameterBasedSqlProcessorFactory, Expression queryExpression, bool useRelationalNulls, - ParameterizedCollectionMode parameterizedCollectionMode) + ParameterTranslationMode collectionParameterTranslationMode) { _memoryCache = memoryCache; _querySqlGeneratorFactory = querySqlGeneratorFactory; _queryExpression = queryExpression; _relationalParameterBasedSqlProcessor = relationalParameterBasedSqlProcessorFactory.Create( - new RelationalParameterBasedSqlProcessorParameters(useRelationalNulls, parameterizedCollectionMode)); + new RelationalParameterBasedSqlProcessorParameters(useRelationalNulls, collectionParameterTranslationMode)); } /// diff --git a/src/efcore/src/EFCore.Relational/Query/Internal/RelationalParameterProcessor.cs b/src/efcore/src/EFCore.Relational/Query/Internal/RelationalParameterProcessor.cs index b955ccae286..f1ed4b087b1 100644 --- a/src/efcore/src/EFCore.Relational/Query/Internal/RelationalParameterProcessor.cs +++ b/src/efcore/src/EFCore.Relational/Query/Internal/RelationalParameterProcessor.cs @@ -128,7 +128,7 @@ private SqlParameterExpression VisitSqlParameter(SqlParameterExpression paramete uniquifiedName, parameter.Type, parameter.IsNullable, - parameter.ShouldBeConstantized, + parameter.TranslationMode, parameter.TypeMapping); return _sqlParameters[newParameter.InvariantName] = newParameter; diff --git a/src/efcore/src/EFCore.Relational/Query/RelationalParameterBasedSqlProcessorParameters.cs b/src/efcore/src/EFCore.Relational/Query/RelationalParameterBasedSqlProcessorParameters.cs index 415a8db6e54..d0bc742fd83 100644 --- a/src/efcore/src/EFCore.Relational/Query/RelationalParameterBasedSqlProcessorParameters.cs +++ b/src/efcore/src/EFCore.Relational/Query/RelationalParameterBasedSqlProcessorParameters.cs @@ -16,17 +16,17 @@ public sealed record RelationalParameterBasedSqlProcessorParameters /// /// Which parametrized collection translation mode should be used. /// - public ParameterizedCollectionMode ParameterizedCollectionMode { get; init; } + public ParameterTranslationMode CollectionParameterTranslationMode { get; init; } /// /// Creates a new instance of . /// /// A value indicating if relational nulls should be used. - /// Which translation mode should be used. + /// Which translation mode should be used. [EntityFrameworkInternal] - public RelationalParameterBasedSqlProcessorParameters(bool useRelationalNulls, ParameterizedCollectionMode parameterizedCollectionMode) + public RelationalParameterBasedSqlProcessorParameters(bool useRelationalNulls, ParameterTranslationMode collectionParameterTranslationMode) { UseRelationalNulls = useRelationalNulls; - ParameterizedCollectionMode = parameterizedCollectionMode; + CollectionParameterTranslationMode = collectionParameterTranslationMode; } } diff --git a/src/efcore/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs b/src/efcore/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs index 848973552c6..18bb222f2f1 100644 --- a/src/efcore/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs +++ b/src/efcore/src/EFCore.Relational/Query/RelationalQueryableMethodTranslatingExpressionVisitor.cs @@ -21,7 +21,7 @@ public partial class RelationalQueryableMethodTranslatingExpressionVisitor : Que private readonly IRelationalTypeMappingSource _typeMappingSource; private readonly ISqlExpressionFactory _sqlExpressionFactory; private readonly bool _subquery; - private readonly ParameterizedCollectionMode _parameterizedCollectionMode; + private readonly ParameterTranslationMode _collectionParameterTranslationMode; /// /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to @@ -64,7 +64,7 @@ public RelationalQueryableMethodTranslatingExpressionVisitor( _typeMappingSource = relationalDependencies.TypeMappingSource; _sqlExpressionFactory = sqlExpressionFactory; _subquery = false; - _parameterizedCollectionMode = RelationalOptionsExtension.Extract(queryCompilationContext.ContextOptions).ParameterizedCollectionMode; + _collectionParameterTranslationMode = RelationalOptionsExtension.Extract(queryCompilationContext.ContextOptions).ParameterizedCollectionMode; } /// @@ -90,7 +90,7 @@ protected RelationalQueryableMethodTranslatingExpressionVisitor( _typeMappingSource = parentVisitor._typeMappingSource; _sqlExpressionFactory = parentVisitor._sqlExpressionFactory; _subquery = true; - _parameterizedCollectionMode = RelationalOptionsExtension.Extract(parentVisitor._queryCompilationContext.ContextOptions).ParameterizedCollectionMode; + _collectionParameterTranslationMode = RelationalOptionsExtension.Extract(parentVisitor._queryCompilationContext.ContextOptions).ParameterizedCollectionMode; } /// @@ -244,7 +244,8 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp && methodCallExpression.Arguments[0] is ParameterQueryRootExpression parameterSource && TranslateExpression(methodCallExpression.Arguments[1]) is SqlExpression item && _sqlTranslator.Visit(parameterSource.QueryParameterExpression) is SqlParameterExpression sqlParameterExpression - && !parameterSource.QueryParameterExpression.ShouldNotBeConstantized) + && (parameterSource.QueryParameterExpression.TranslationMode is ParameterTranslationMode.Constant + or null)) { var inExpression = _sqlExpressionFactory.In(item, sqlParameterExpression); var selectExpression = new SelectExpression(inExpression, _sqlAliasManager); @@ -298,26 +299,24 @@ JsonScalarExpression jsonScalar var tableAlias = _sqlAliasManager.GenerateTableAlias(sqlParameterExpression.Name.TrimStart('_')); - var constants = queryParameter.ShouldBeConstantized - || (_parameterizedCollectionMode is ParameterizedCollectionMode.Constants - && !queryParameter.ShouldNotBeConstantized); - var multipleParameters = _parameterizedCollectionMode is ParameterizedCollectionMode.MultipleParameters - && !queryParameter.ShouldNotBeConstantized; - if (constants || multipleParameters) - { - var valuesExpression = new ValuesExpression( - tableAlias, - sqlParameterExpression, - [ValuesOrderingColumnName, ValuesValueColumnName]); - return CreateShapedQueryExpressionForValuesExpression( - valuesExpression, - tableAlias, - parameterQueryRootExpression.ElementType, - sqlParameterExpression.TypeMapping, - sqlParameterExpression.IsNullable); - } - - return TranslatePrimitiveCollection(sqlParameterExpression, property: null, tableAlias); + return (queryParameter.TranslationMode ?? _collectionParameterTranslationMode) switch + { + ParameterTranslationMode.Constant or ParameterTranslationMode.MultipleParameters + => CreateShapedQueryExpressionForValuesExpression( + new ValuesExpression( + tableAlias, + sqlParameterExpression, + [ValuesOrderingColumnName, ValuesValueColumnName]), + tableAlias, + parameterQueryRootExpression.ElementType, + sqlParameterExpression.TypeMapping, + sqlParameterExpression.IsNullable), + + ParameterTranslationMode.Parameter + => TranslatePrimitiveCollection(sqlParameterExpression, property: null, tableAlias), + + _ => throw new UnreachableException() + }; } /// diff --git a/src/efcore/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs b/src/efcore/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs index aec6e3cc14d..dbbe1c92358 100644 --- a/src/efcore/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs +++ b/src/efcore/src/EFCore.Relational/Query/RelationalShapedQueryCompilingExpressionVisitor.cs @@ -19,7 +19,7 @@ public partial class RelationalShapedQueryCompilingExpressionVisitor : ShapedQue private readonly bool _threadSafetyChecksEnabled; private readonly bool _detailedErrorsEnabled; private readonly bool _useRelationalNulls; - private readonly ParameterizedCollectionMode _parameterizedCollectionMode; + private readonly ParameterTranslationMode _collectionParameterTranslationMode; private readonly bool _isPrecompiling; private readonly RelationalParameterBasedSqlProcessor _relationalParameterBasedSqlProcessor; @@ -55,7 +55,7 @@ public RelationalShapedQueryCompilingExpressionVisitor( _relationalParameterBasedSqlProcessor = relationalDependencies.RelationalParameterBasedSqlProcessorFactory.Create( - new RelationalParameterBasedSqlProcessorParameters(_useRelationalNulls, _parameterizedCollectionMode)); + new RelationalParameterBasedSqlProcessorParameters(_useRelationalNulls, _collectionParameterTranslationMode)); _querySqlGeneratorFactory = relationalDependencies.QuerySqlGeneratorFactory; _contextType = queryCompilationContext.ContextType; @@ -63,7 +63,7 @@ public RelationalShapedQueryCompilingExpressionVisitor( _threadSafetyChecksEnabled = dependencies.CoreSingletonOptions.AreThreadSafetyChecksEnabled; _detailedErrorsEnabled = dependencies.CoreSingletonOptions.AreDetailedErrorsEnabled; _useRelationalNulls = RelationalOptionsExtension.Extract(queryCompilationContext.ContextOptions).UseRelationalNulls; - _parameterizedCollectionMode = RelationalOptionsExtension.Extract(queryCompilationContext.ContextOptions).ParameterizedCollectionMode; + _collectionParameterTranslationMode = RelationalOptionsExtension.Extract(queryCompilationContext.ContextOptions).ParameterizedCollectionMode; _isPrecompiling = queryCompilationContext.IsPrecompiling; } @@ -500,7 +500,7 @@ private Expression CreateRelationalCommandResolverExpression(Expression queryExp RelationalDependencies.RelationalParameterBasedSqlProcessorFactory, queryExpression, _useRelationalNulls, - _parameterizedCollectionMode); + _collectionParameterTranslationMode); var commandLiftableConstant = RelationalDependencies.RelationalLiftableConstantFactory.CreateLiftableConstant( relationalCommandCache, @@ -751,7 +751,7 @@ Expression> Generate _relationalDependenciesRelationalParameterBasedSqlProcessorFactoryProperty), Constant(queryExpression), Constant(_useRelationalNulls), - Constant(_parameterizedCollectionMode, typeof(ParameterizedCollectionMode))), + Constant(_collectionParameterTranslationMode, typeof(ParameterTranslationMode))), contextParameter); } } diff --git a/src/efcore/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs b/src/efcore/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs index c8f4ec36332..fb89e8c214e 100644 --- a/src/efcore/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs +++ b/src/efcore/src/EFCore.Relational/Query/RelationalSqlTranslatingExpressionVisitor.cs @@ -516,7 +516,7 @@ protected override Expression VisitExtension(Expression extensionExpression) name: queryParameter.Name, queryParameter.Type, nullable: false, - queryParameter.ShouldBeConstantized, + queryParameter.TranslationMode, typeMapping: null); } @@ -525,7 +525,7 @@ protected override Expression VisitExtension(Expression extensionExpression) name: queryParameter.Name, queryParameter.Type, queryParameter.Type.IsNullableType(), - queryParameter.ShouldBeConstantized, + queryParameter.TranslationMode, typeMapping: null); case StructuralTypeShaperExpression shaper: diff --git a/src/efcore/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs b/src/efcore/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs index 48c1602fbaa..a279f21889f 100644 --- a/src/efcore/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs +++ b/src/efcore/src/EFCore.Relational/Query/SqlExpressions/SqlParameterExpression.cs @@ -17,7 +17,7 @@ public sealed class SqlParameterExpression : SqlExpression /// The of the expression. /// The associated with the expression. public SqlParameterExpression(string name, Type type, RelationalTypeMapping? typeMapping) - : this(invariantName: name, name: name, type.UnwrapNullableType(), type.IsNullableType(), shouldBeConstantized: false, typeMapping) + : this(invariantName: name, name: name, type.UnwrapNullableType(), type.IsNullableType(), translationMode: null, typeMapping) { } @@ -31,21 +31,21 @@ public SqlParameterExpression(string name, Type type, RelationalTypeMapping? typ /// /// The of the expression. /// Whether this parameter can have null values. - /// Whether the user has indicated that this query parameter should be inlined as a constant. + /// How the parameter should be handled. /// The associated with the expression. public SqlParameterExpression( string invariantName, string name, Type type, bool nullable, - bool shouldBeConstantized, + ParameterTranslationMode? translationMode, RelationalTypeMapping? typeMapping) : base(type.UnwrapNullableType(), typeMapping) { InvariantName = invariantName; Name = name; IsNullable = nullable; - ShouldBeConstantized = shouldBeConstantized; + TranslationMode = translationMode; } /// @@ -65,9 +65,9 @@ public SqlParameterExpression( public bool IsNullable { get; } /// - /// Whether the user has indicated that this query parameter should be inlined as a constant. + /// How the parameter should be handled. /// - public bool ShouldBeConstantized { get; } + public ParameterTranslationMode? TranslationMode { get; } /// /// Applies supplied type mapping to this expression. @@ -75,7 +75,7 @@ public SqlParameterExpression( /// A relational type mapping to apply. /// A new expression which has supplied type mapping. public SqlExpression ApplyTypeMapping(RelationalTypeMapping? typeMapping) - => new SqlParameterExpression(InvariantName, Name, Type, IsNullable, ShouldBeConstantized, typeMapping); + => new SqlParameterExpression(InvariantName, Name, Type, IsNullable, TranslationMode, typeMapping); /// protected override Expression VisitChildren(ExpressionVisitor visitor) diff --git a/src/efcore/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs b/src/efcore/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs index 32af300b2c1..190d56525b8 100644 --- a/src/efcore/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs +++ b/src/efcore/src/EFCore.Relational/Query/SqlNullabilityProcessor.cs @@ -39,7 +39,7 @@ public SqlNullabilityProcessor( { Dependencies = dependencies; UseRelationalNulls = parameters.UseRelationalNulls; - ParameterizedCollectionMode = parameters.ParameterizedCollectionMode; + CollectionParameterTranslationMode = parameters.CollectionParameterTranslationMode; _sqlExpressionFactory = dependencies.SqlExpressionFactory; _nonNullableColumns = []; @@ -61,7 +61,7 @@ public SqlNullabilityProcessor( /// /// A value indicating what translation mode to use. /// - public virtual ParameterizedCollectionMode ParameterizedCollectionMode { get; } + public virtual ParameterTranslationMode CollectionParameterTranslationMode { get; } /// /// Dictionary of current parameter values in use. @@ -126,10 +126,9 @@ protected override Expression VisitExtension(Expression node) var processedValues = new List(); - switch (ParameterizedCollectionMode) + switch (valuesParameter.TranslationMode ?? CollectionParameterTranslationMode) { - case ParameterizedCollectionMode.MultipleParameters - when !valuesParameter.ShouldBeConstantized: + case ParameterTranslationMode.MultipleParameters: { var expandedParameters = _collectionParameterExpansionMap.GetOrAddNew(valuesParameter); for (var i = 0; i < values.Count; i++) @@ -155,11 +154,7 @@ protected override Expression VisitExtension(Expression node) break; } - case ParameterizedCollectionMode.Constants: - case ParameterizedCollectionMode.Parameter - when valuesParameter.ShouldBeConstantized: - case ParameterizedCollectionMode.MultipleParameters - when valuesParameter.ShouldBeConstantized: + case ParameterTranslationMode.Constant: { foreach (var value in values) { @@ -819,18 +814,6 @@ InExpression ProcessInExpressionValues( processedValues = []; - var useParameters = ParameterizedCollectionMode is ParameterizedCollectionMode.MultipleParameters - && !valuesParameter.ShouldBeConstantized; - var useConstants = - ParameterizedCollectionMode is ParameterizedCollectionMode.Constants - || - (ParameterizedCollectionMode is ParameterizedCollectionMode.Parameter - && valuesParameter.ShouldBeConstantized) - || - (ParameterizedCollectionMode is ParameterizedCollectionMode.MultipleParameters - && valuesParameter.ShouldBeConstantized); - var useParameter = ParameterizedCollectionMode is ParameterizedCollectionMode.Parameter - && !valuesParameter.ShouldBeConstantized; var expandedParameters = _collectionParameterExpansionMap.GetOrAddNew(valuesParameter); var expandedParametersCounter = 0; for (var i = 0; i < values.Count; i++) @@ -841,11 +824,11 @@ ParameterizedCollectionMode is ParameterizedCollectionMode.Constants continue; } - switch (useParameters, useConstants, useParameter) + switch (valuesParameter.TranslationMode ?? CollectionParameterTranslationMode) { - case (true, false, false): + case ParameterTranslationMode.MultipleParameters: // see #36311 for more info - case (false, false, true): + case ParameterTranslationMode.Parameter: { // Create parameter for value if we didn't create it yet, // otherwise reuse it. @@ -863,7 +846,7 @@ ParameterizedCollectionMode is ParameterizedCollectionMode.Constants break; } - case (false, true, false): + case ParameterTranslationMode.Constant: { processedValues.Add(_sqlExpressionFactory.Constant(values[i], values[i]?.GetType() ?? typeof(object), sensitive: true, elementTypeMapping)); @@ -1425,7 +1408,7 @@ protected virtual SqlExpression VisitSqlParameter( nullable = false; - if (sqlParameterExpression.ShouldBeConstantized) + if (sqlParameterExpression.TranslationMode is ParameterTranslationMode.Constant) { var parameters = ParametersFacade.GetParametersAndDisableSqlCaching(); diff --git a/src/efcore/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs b/src/efcore/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs index ea4b96ed806..3215b65578e 100644 --- a/src/efcore/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs +++ b/src/efcore/src/EFCore.SqlServer/Query/Internal/SqlServerSqlNullabilityProcessor.cs @@ -187,8 +187,7 @@ protected override Expression VisitExtension(Expression node) switch (node) { case ValuesExpression { ValuesParameter: SqlParameterExpression valuesParameter } valuesExpression - when ParameterizedCollectionMode is ParameterizedCollectionMode.MultipleParameters - && !valuesParameter.ShouldBeConstantized: + when (valuesParameter.TranslationMode ?? CollectionParameterTranslationMode) is ParameterTranslationMode.MultipleParameters: { Check.DebugAssert(valuesParameter.TypeMapping is not null); Check.DebugAssert(valuesParameter.TypeMapping.ElementTypeMapping is not null); @@ -234,8 +233,7 @@ protected override SqlExpression VisitIn(InExpression inExpression, bool allowOp switch (inExpression.ValuesParameter) { case SqlParameterExpression valuesParameter - when ParameterizedCollectionMode is ParameterizedCollectionMode.MultipleParameters - && !valuesParameter.ShouldBeConstantized: + when (valuesParameter.TranslationMode ?? CollectionParameterTranslationMode) is ParameterTranslationMode.MultipleParameters: { Check.DebugAssert(valuesParameter.TypeMapping is not null); Check.DebugAssert(valuesParameter.TypeMapping.ElementTypeMapping is not null); diff --git a/src/efcore/src/EFCore.Relational/ParameterizedCollectionMode.cs b/src/efcore/src/EFCore/ParameterTranslationMode.cs similarity index 88% rename from src/efcore/src/EFCore.Relational/ParameterizedCollectionMode.cs rename to src/efcore/src/EFCore/ParameterTranslationMode.cs index 89f48bea90a..964a53688e9 100644 --- a/src/efcore/src/EFCore.Relational/ParameterizedCollectionMode.cs +++ b/src/efcore/src/EFCore/ParameterTranslationMode.cs @@ -6,8 +6,21 @@ namespace Microsoft.EntityFrameworkCore; /// /// Indicates how parameterized collections are translated into SQL. /// -public enum ParameterizedCollectionMode +public enum ParameterTranslationMode { + /// + /// Instructs EF to translate the collection to a set of parameters: + /// WHERE [x].[Id] IN (@ids1, @ids2, @ids3). + /// + /// + /// + /// Note that it's possible to cause EF to translate a specific collection in a specific query to parameter by wrapping the + /// parameterized collection in EF.MultipleParameters: Where(x => EF.MultipleParameters(ids).Contains(x.Id). This overrides + /// the default. + /// + /// + MultipleParameters = 0, + /// /// Instructs EF to translate the collection to a set of constants: /// WHERE [x].[Id] IN (1, 2, 3). @@ -23,7 +36,7 @@ public enum ParameterizedCollectionMode /// the default. /// /// - Constants, + Constant = 1, /// /// Instructs EF to translate the collection to a single array-like parameter: @@ -39,18 +52,5 @@ public enum ParameterizedCollectionMode /// the default. /// /// - Parameter, - - /// - /// Instructs EF to translate the collection to a set of parameters: - /// WHERE [x].[Id] IN (@ids1, @ids2, @ids3). - /// - /// - /// - /// Note that it's possible to cause EF to translate a specific collection in a specific query to parameter by wrapping the - /// parameterized collection in : Where(x => EF.MultipleParameters(ids).Contains(x.Id). This overrides - /// the default. - /// - /// - MultipleParameters, + Parameter = 2, } diff --git a/src/efcore/src/EFCore/Properties/CoreStrings.Designer.cs b/src/efcore/src/EFCore/Properties/CoreStrings.Designer.cs index 2de56528926..e38cb0db359 100644 --- a/src/efcore/src/EFCore/Properties/CoreStrings.Designer.cs +++ b/src/efcore/src/EFCore/Properties/CoreStrings.Designer.cs @@ -358,14 +358,6 @@ public static string CanOnlyConfigureExistingNavigations(object? navigationName, GetString("CanOnlyConfigureExistingNavigations", "0_navigationName", "1_entityType"), navigationName, entityType); - /// - /// The entity type '{entityType}' is configured to use the '{changeTrackingStrategy}' change tracking strategy, but does not implement the required '{notificationInterface}' interface. Implement '{notificationInterface}' on '{entityType}' or use a different change tracking strategy. - /// - public static string ChangeTrackingInterfaceMissing(object? entityType, object? changeTrackingStrategy, object? notificationInterface) - => string.Format( - GetString("ChangeTrackingInterfaceMissing", nameof(entityType), nameof(changeTrackingStrategy), nameof(notificationInterface)), - entityType, changeTrackingStrategy, notificationInterface); - /// /// Unable to save changes because a circular dependency was detected in the data to be saved: '{cycle}'. /// @@ -1125,10 +1117,12 @@ public static string EFConstantNotSupportedInPrecompiledQueries => GetString("EFConstantNotSupportedInPrecompiledQueries"); /// - /// The EF.Constant<T> method may only be used with an argument that can be evaluated client-side and does not contain any reference to database-side entities. + /// The {methodName} method may only be used with an argument that can be evaluated client-side and does not contain any reference to database-side entities. /// - public static string EFConstantWithNonEvaluatableArgument - => GetString("EFConstantWithNonEvaluatableArgument"); + public static string EFMethodWithNonEvaluatableArgument(object? methodName) + => string.Format( + GetString("EFMethodWithNonEvaluatableArgument", nameof(methodName)), + methodName); /// /// The EF.Parameter<T> method may only be used within Entity Framework LINQ queries. @@ -1136,12 +1130,6 @@ public static string EFConstantWithNonEvaluatableArgument public static string EFParameterInvoked => GetString("EFParameterInvoked"); - /// - /// The EF.Parameter<T> method may only be used with an argument that can be evaluated client-side and does not contain any reference to database-side entities. - /// - public static string EFParameterWithNonEvaluatableArgument - => GetString("EFParameterWithNonEvaluatableArgument"); - /// /// Complex type '{complexType}' has no properties defines. Configure at least one property or don't include this type in the model. /// @@ -1452,6 +1440,14 @@ public static string GraphDoesNotContainVertex(object? vertex) public static string HiLoBadBlockSize => GetString("HiLoBadBlockSize"); + /// + /// The entity type '{entityType}' is configured to use the '{changeTrackingStrategy}' change tracking strategy, but does not implement the required '{notificationInterface}' interface. Implement '{notificationInterface}' on '{entityType}' or use a different change tracking strategy. + /// + public static string ChangeTrackingInterfaceMissing(object? entityType, object? changeTrackingStrategy, object? notificationInterface) + => string.Format( + GetString("ChangeTrackingInterfaceMissing", nameof(entityType), nameof(changeTrackingStrategy), nameof(notificationInterface)), + entityType, changeTrackingStrategy, notificationInterface); + /// /// A relationship cycle involving the primary keys of the following entity types was detected: '{entityType}'. This would prevent any entity to be inserted without violating the store constraints. Review the foreign keys defined on the primary keys and either remove or use other properties for at least one of them. /// diff --git a/src/efcore/src/EFCore/Properties/CoreStrings.resx b/src/efcore/src/EFCore/Properties/CoreStrings.resx index 3df16dbe847..ad5fc60c153 100644 --- a/src/efcore/src/EFCore/Properties/CoreStrings.resx +++ b/src/efcore/src/EFCore/Properties/CoreStrings.resx @@ -243,9 +243,6 @@ Navigation '{1_entityType}.{0_navigationName}' was not found. Please add the navigation to the entity type before configuring it. - - The entity type '{entityType}' is configured to use the '{changeTrackingStrategy}' change tracking strategy, but does not implement the required '{notificationInterface}' interface. Implement '{notificationInterface}' on '{entityType}' or use a different change tracking strategy. - Unable to save changes because a circular dependency was detected in the data to be saved: '{cycle}'. @@ -537,15 +534,12 @@ The EF.Constant<T> method is not supported when using precompiled queries. - - The EF.Constant<T> method may only be used with an argument that can be evaluated client-side and does not contain any reference to database-side entities. + + The {methodName} method may only be used with an argument that can be evaluated client-side and does not contain any reference to database-side entities. The EF.Parameter<T> method may only be used within Entity Framework LINQ queries. - - The EF.Parameter<T> method may only be used with an argument that can be evaluated client-side and does not contain any reference to database-side entities. - Complex type '{complexType}' has no properties defines. Configure at least one property or don't include this type in the model. @@ -666,6 +660,9 @@ The block size used for Hi-Lo value generation is not positive. The Hi-Lo generator is usually backed by a SQL sequence and this means that the sequence increment must be positive. + + The entity type '{entityType}' is configured to use the '{changeTrackingStrategy}' change tracking strategy, but does not implement the required '{notificationInterface}' interface. Implement '{notificationInterface}' on '{entityType}' or use a different change tracking strategy. + A relationship cycle involving the primary keys of the following entity types was detected: '{entityType}'. This would prevent any entity to be inserted without violating the store constraints. Review the foreign keys defined on the primary keys and either remove or use other properties for at least one of them. diff --git a/src/efcore/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs b/src/efcore/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs index 44fdec7dbc0..afb319d52c0 100644 --- a/src/efcore/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs +++ b/src/efcore/src/EFCore/Query/Internal/ExpressionTreeFuncletizer.cs @@ -939,7 +939,7 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCall) if (!argumentState.IsEvaluatable) { - throw new InvalidOperationException(CoreStrings.EFConstantWithNonEvaluatableArgument); + throw new InvalidOperationException(CoreStrings.EFMethodWithNonEvaluatableArgument("EF.Constant")); } // Even EF.Constant will be parameter here. @@ -952,21 +952,17 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCall) case nameof(EF.Parameter): { - var argument = Visit(methodCall.Arguments[0], out var argumentState); - - if (!argumentState.IsEvaluatable) - { - throw new InvalidOperationException(CoreStrings.EFParameterWithNonEvaluatableArgument); - } - - argumentState = argumentState with { StateType = StateType.EvaluatableWithCapturedVariable }; - var evaluatedArgument = ProcessEvaluatableRoot(argument, ref argumentState, forceEvaluation: true); - _state = argumentState; - return Call(method, evaluatedArgument); + return HandleParameter(methodCall, "EF.Parameter"); } } } + // EF.MultipleParameters is defined in Relational, hence the hardcoded values here. + if (method is { Name: "MultipleParameters", DeclaringType.FullName: "Microsoft.EntityFrameworkCore.EFExtensions" }) + { + return HandleParameter(methodCall, "EF.MultipleParameters"); + } + // .NET 10 made changes to overload resolution to prefer Span-based overloads when those exist ("first-class spans"). // Unfortunately, the LINQ interpreter does not support ref structs, so we rewrite e.g. MemoryExtensions.Contains to // Enumerable.Contains here. See https://github.com/dotnet/runtime/issues/109757,. @@ -1116,6 +1112,21 @@ static bool TryUnwrapSpanImplicitCast(Expression expression, [NotNullWhen(true)] } return methodCall.Update(@object, ((IReadOnlyList?)arguments) ?? methodCall.Arguments); + + Expression HandleParameter(MethodCallExpression methodCall, string methodName) + { + var argument = Visit(methodCall.Arguments[0], out var argumentState); + + if (!argumentState.IsEvaluatable) + { + throw new InvalidOperationException(CoreStrings.EFMethodWithNonEvaluatableArgument(methodName)); + } + + argumentState = argumentState with { StateType = StateType.EvaluatableWithCapturedVariable }; + var evaluatedArgument = ProcessEvaluatableRoot(argument, ref argumentState, forceEvaluation: true); + _state = argumentState; + return Call(methodCall.Method, evaluatedArgument); + } } /// @@ -1977,8 +1988,7 @@ private static StateType CombineStateTypes(StateType stateType1, StateType state return _parameterizedValues[evaluatableRoot] = new QueryParameterExpression( parameterName, evaluatableRoot.Type, - shouldBeConstantized: false, - shouldNotBeConstantized: false, + translationMode: null, isNonNullableReferenceType); } diff --git a/src/efcore/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs b/src/efcore/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs index 187b0b7263c..80dbb37f040 100644 --- a/src/efcore/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs +++ b/src/efcore/src/EFCore/Query/Internal/QueryableMethodNormalizingExpressionVisitor.cs @@ -127,20 +127,23 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp var queryParameter = (QueryParameterExpression)Visit(methodCallExpression.Arguments[0]); return new QueryParameterExpression( - queryParameter.Name, queryParameter.Type, shouldBeConstantized: true, shouldNotBeConstantized: false, + queryParameter.Name, queryParameter.Type, translationMode: ParameterTranslationMode.Constant, queryParameter.IsNonNullableReferenceType); } case nameof(EF.Parameter): { - var queryParameter = (QueryParameterExpression)Visit(methodCallExpression.Arguments[0]); - return new QueryParameterExpression( - queryParameter.Name, queryParameter.Type, shouldBeConstantized: false, shouldNotBeConstantized: true, - queryParameter.IsNonNullableReferenceType); + return HandleParameter(methodCallExpression, ParameterTranslationMode.Parameter); } } } + // EF.MultipleParameters is defined in Relational, hence the hardcoded values here. + if (method is { Name: "MultipleParameters", DeclaringType.FullName: "Microsoft.EntityFrameworkCore.EFExtensions" }) + { + return HandleParameter(methodCallExpression, ParameterTranslationMode.MultipleParameters); + } + // Normalize list[x] to list.ElementAt(x) if (methodCallExpression is { @@ -236,6 +239,14 @@ protected override Expression VisitMethodCall(MethodCallExpression methodCallExp } return visitedExpression; + + Expression HandleParameter(MethodCallExpression methodCallExpression, ParameterTranslationMode parameterTranslationMode) + { + var queryParameter = (QueryParameterExpression)Visit(methodCallExpression.Arguments[0]); + return new QueryParameterExpression( + queryParameter.Name, queryParameter.Type, parameterTranslationMode, + queryParameter.IsNonNullableReferenceType); + } } private static void VerifyReturnType(Expression expression, ParameterExpression lambdaParameter) diff --git a/src/efcore/src/EFCore/Query/QueryParameterExpression.cs b/src/efcore/src/EFCore/Query/QueryParameterExpression.cs index 696ff1f3b16..dde4c03c09f 100644 --- a/src/efcore/src/EFCore/Query/QueryParameterExpression.cs +++ b/src/efcore/src/EFCore/Query/QueryParameterExpression.cs @@ -14,31 +14,30 @@ namespace Microsoft.EntityFrameworkCore.Query; public class QueryParameterExpression : Expression, IPrintableExpression { /// - /// Creates a new instance of the class with associated query provider. + /// Creates a new instance of the class with associated query provider. /// public QueryParameterExpression(string name, Type type) - : this(name, type, shouldBeConstantized: false, shouldNotBeConstantized: false, isNonNullableReferenceType: false) + : this(name, type, translationMode: null, isNonNullableReferenceType: false) { } /// - /// Creates a new instance of the class with associated query provider. + /// Creates a new instance of the class with associated query provider. /// - public QueryParameterExpression(string name, Type type, bool shouldBeConstantized, bool shouldNotBeConstantized) - : this(name, type, shouldBeConstantized, shouldNotBeConstantized, isNonNullableReferenceType: false) + public QueryParameterExpression(string name, Type type, ParameterTranslationMode translationMode) + : this(name, type, translationMode, isNonNullableReferenceType: false) { } /// - /// Creates a new instance of the class with associated query provider. + /// Creates a new instance of the class with associated query provider. /// [Experimental(EFDiagnostics.PrecompiledQueryExperimental)] - public QueryParameterExpression(string name, Type type, bool shouldBeConstantized, bool shouldNotBeConstantized, bool isNonNullableReferenceType) + public QueryParameterExpression(string name, Type type, ParameterTranslationMode? translationMode, bool isNonNullableReferenceType) { Name = name; Type = type; - ShouldBeConstantized = shouldBeConstantized; - ShouldNotBeConstantized = shouldNotBeConstantized; + TranslationMode = translationMode; IsNonNullableReferenceType = isNonNullableReferenceType; } @@ -61,14 +60,9 @@ public QueryParameterExpression(string name, Type type, bool shouldBeConstantize public virtual bool IsNonNullableReferenceType { get; } /// - /// Whether the user has indicated that this query parameter should be inlined as a constant. + /// How should the parameter be handled. /// - public virtual bool ShouldBeConstantized { get; } - - /// - /// Whether the user has indicated that this query parameter shouldn't be inlined as a constant. - /// - public virtual bool ShouldNotBeConstantized { get; } + public virtual ParameterTranslationMode? TranslationMode { get; } /// public override ExpressionType NodeType @@ -92,11 +86,10 @@ public override bool Equals(object? obj) private bool Equals(QueryParameterExpression queryParameterExpression) => Name == queryParameterExpression.Name && Type == queryParameterExpression.Type - && ShouldBeConstantized == queryParameterExpression.ShouldBeConstantized - && ShouldNotBeConstantized == queryParameterExpression.ShouldNotBeConstantized + && TranslationMode == queryParameterExpression.TranslationMode && IsNonNullableReferenceType == queryParameterExpression.IsNonNullableReferenceType; /// public override int GetHashCode() - => HashCode.Combine(Name, Type, ShouldBeConstantized, ShouldNotBeConstantized, IsNonNullableReferenceType); + => HashCode.Combine(Name, Type, TranslationMode, IsNonNullableReferenceType); } diff --git a/src/efcore/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs b/src/efcore/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs index 1cd086ec586..97180c4cf39 100644 --- a/src/efcore/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs +++ b/src/efcore/test/EFCore.Cosmos.FunctionalTests/Query/NorthwindWhereQueryCosmosTest.cs @@ -2338,8 +2338,8 @@ public override async Task EF_Constant_does_not_parameterized_as_part_of_bigger_ public override async Task EF_Constant_with_non_evaluatable_argument_throws(bool async) { await base.EF_Constant_with_non_evaluatable_argument_throws(async); - AssertSql( - ); + + AssertSql(); } public override Task EF_Parameter(bool async) diff --git a/src/efcore/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs b/src/efcore/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs index 2496b692e1d..a572b1d9090 100644 --- a/src/efcore/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs +++ b/src/efcore/test/EFCore.Relational.Specification.Tests/Query/AdHocMiscellaneousQueryRelationalTestBase.cs @@ -20,6 +20,8 @@ protected void ClearLog() protected void AssertSql(params string[] expected) => TestSqlLoggerFactory.AssertBaseline(expected); + protected abstract DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterTranslationMode parameterizedCollectionMode); + #region 2951 [ConditionalFact] @@ -268,8 +270,6 @@ public class Entity #region Inlined redacting - protected abstract DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterizedCollectionMode parameterizedCollectionMode); - [ConditionalTheory] [MemberData(nameof(InlinedRedactingData))] public virtual async Task Check_inlined_constants_redacting(bool async, bool enableSensitiveDataLogging) @@ -277,7 +277,7 @@ public virtual async Task Check_inlined_constants_redacting(bool async, bool ena var contextFactory = await InitializeAsync( onConfiguring: o => { - SetParameterizedCollectionMode(o, ParameterizedCollectionMode.Constants); + SetParameterizedCollectionMode(o, ParameterTranslationMode.Constant); o.EnableSensitiveDataLogging(enableSensitiveDataLogging); }); using var context = contextFactory.CreateContext(); @@ -324,7 +324,7 @@ public class TestEntity public async Task Entity_equality_with_Contains_and_Parameter(bool async) { var contextFactory = await InitializeAsync( - onConfiguring: o => SetParameterizedCollectionMode(o, ParameterizedCollectionMode.Parameter)); + onConfiguring: o => SetParameterizedCollectionMode(o, ParameterTranslationMode.Parameter)); using var context = contextFactory.CreateContext(); List details = [new Context36311.BlogDetails { Id = 1 }, new Context36311.BlogDetails { Id = 2 }]; diff --git a/src/efcore/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs b/src/efcore/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs index 2cc15f6fafd..e5132067c77 100644 --- a/src/efcore/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs +++ b/src/efcore/test/EFCore.Relational.Specification.Tests/Query/NonSharedPrimitiveCollectionsQueryRelationalTestBase.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Linq; + namespace Microsoft.EntityFrameworkCore.Query; #nullable disable @@ -12,7 +14,7 @@ public abstract class NonSharedPrimitiveCollectionsQueryRelationalTestBase(NonSh public override Task Array_of_byte() => AssertTranslationFailed(() => TestArray((byte)1, (byte)2)); - protected abstract DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterizedCollectionMode parameterizedCollectionMode); + protected abstract DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterTranslationMode parameterizedCollectionMode); [ConditionalFact] public virtual async Task Column_collection_inside_json_owned_entity() @@ -36,11 +38,15 @@ public virtual async Task Column_collection_inside_json_owned_entity() Assert.Equivalent(new[] { "foo", "bar" }, result.Owned.Strings); } - [ConditionalFact] - public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_constants() + protected static IEnumerable ParameterTranslationModeValues() + => Enum.GetValues().Select(x => [x]); + + [ConditionalTheory] + [MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) { var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterizedCollectionMode.Constants), + onConfiguring: b => SetParameterizedCollectionMode(b, mode), seed: context => { context.AddRange( @@ -56,11 +62,12 @@ public virtual async Task Parameter_collection_Count_with_column_predicate_with_ Assert.Equivalent(new[] { 100 }, result); } - [ConditionalFact] - public virtual async Task Parameter_collection_Contains_with_default_constants() + [ConditionalTheory] + [MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) { var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterizedCollectionMode.Constants), + onConfiguring: b => SetParameterizedCollectionMode(b, mode), seed: context => { context.AddRange( @@ -77,53 +84,12 @@ public virtual async Task Parameter_collection_Contains_with_default_constants() Assert.Equivalent(new[] { 2 }, result); } - [ConditionalFact] - public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter() - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterizedCollectionMode.Constants), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ids = new[] { 2, 999 }; - var result = await context.Set().Where(c => EF.Parameter(ids).Count(i => i > c.Id) == 1).Select(x => x.Id) - .ToListAsync(); - Assert.Equivalent(new[] { 100 }, result); - } - - [ConditionalFact] - public virtual async Task Parameter_collection_Contains_with_default_constants_EF_Parameter() - { - var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterizedCollectionMode.Constants), - seed: context => - { - context.AddRange( - new TestEntity { Id = 1 }, - new TestEntity { Id = 2 }, - new TestEntity { Id = 100 }); - return context.SaveChangesAsync(); - }); - - await using var context = contextFactory.CreateContext(); - - var ints = new[] { 2, 999 }; - var result = await context.Set().Where(c => EF.Parameter(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); - Assert.Equivalent(new[] { 2 }, result); - } - - [ConditionalFact] - public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_parameter() + [ConditionalTheory] + [MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) { var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterizedCollectionMode.Parameter), + onConfiguring: b => SetParameterizedCollectionMode(b, mode), seed: context => { context.AddRange( @@ -135,15 +101,16 @@ public virtual async Task Parameter_collection_Count_with_column_predicate_with_ await using var context = contextFactory.CreateContext(); var ids = new[] { 2, 999 }; - var result = await context.Set().Where(c => ids.Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); + var result = await context.Set().Where(c => EF.Constant(ids).Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); Assert.Equivalent(new[] { 100 }, result); } - [ConditionalFact] - public virtual async Task Parameter_collection_Contains_with_default_parameter() + [ConditionalTheory] + [MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) { var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterizedCollectionMode.Parameter), + onConfiguring: b => SetParameterizedCollectionMode(b, mode), seed: context => { context.AddRange( @@ -156,15 +123,16 @@ public virtual async Task Parameter_collection_Contains_with_default_parameter() await using var context = contextFactory.CreateContext(); var ints = new[] { 2, 999 }; - var result = await context.Set().Where(c => ints.Contains(c.Id)).Select(x => x.Id).ToListAsync(); + var result = await context.Set().Where(c => EF.Constant(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); Assert.Equivalent(new[] { 2 }, result); } - [ConditionalFact] - public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_parameter_EF_Constant() + [ConditionalTheory] + [MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(ParameterTranslationMode mode) { var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterizedCollectionMode.Parameter), + onConfiguring: b => SetParameterizedCollectionMode(b, mode), seed: context => { context.AddRange( @@ -176,15 +144,17 @@ public virtual async Task Parameter_collection_Count_with_column_predicate_with_ await using var context = contextFactory.CreateContext(); var ids = new[] { 2, 999 }; - var result = await context.Set().Where(c => EF.Constant(ids).Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); + var result = await context.Set().Where(c => EF.Parameter(ids).Count(i => i > c.Id) == 1).Select(x => x.Id) + .ToListAsync(); Assert.Equivalent(new[] { 100 }, result); } - [ConditionalFact] - public virtual async Task Parameter_collection_Contains_with_default_parameter_EF_Constant() + [ConditionalTheory] + [MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) { var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterizedCollectionMode.Parameter), + onConfiguring: b => SetParameterizedCollectionMode(b, mode), seed: context => { context.AddRange( @@ -197,15 +167,16 @@ public virtual async Task Parameter_collection_Contains_with_default_parameter_E await using var context = contextFactory.CreateContext(); var ints = new[] { 2, 999 }; - var result = await context.Set().Where(c => EF.Constant(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); + var result = await context.Set().Where(c => EF.Parameter(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); Assert.Equivalent(new[] { 2 }, result); } - [ConditionalFact] - public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_multiple_parameters() + [ConditionalTheory] + [MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) { var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterizedCollectionMode.MultipleParameters), + onConfiguring: b => SetParameterizedCollectionMode(b, mode), seed: context => { context.AddRange( @@ -217,15 +188,17 @@ public virtual async Task Parameter_collection_Count_with_column_predicate_with_ await using var context = contextFactory.CreateContext(); var ids = new[] { 2, 999 }; - var result = await context.Set().Where(c => ids.Count(i => i > c.Id) == 1).Select(x => x.Id).ToListAsync(); + var result = await context.Set().Where(c => EF.MultipleParameters(ids).Count(i => i > c.Id) == 1).Select(x => x.Id) + .ToListAsync(); Assert.Equivalent(new[] { 100 }, result); } - [ConditionalFact] - public virtual async Task Parameter_collection_Contains_with_default_multiple_parameters() + [ConditionalTheory] + [MemberData(nameof(ParameterTranslationModeValues))] + public virtual async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) { var contextFactory = await InitializeAsync( - onConfiguring: b => SetParameterizedCollectionMode(b, ParameterizedCollectionMode.MultipleParameters), + onConfiguring: b => SetParameterizedCollectionMode(b, mode), seed: context => { context.AddRange( @@ -238,7 +211,7 @@ public virtual async Task Parameter_collection_Contains_with_default_multiple_pa await using var context = contextFactory.CreateContext(); var ints = new[] { 2, 999 }; - var result = await context.Set().Where(c => ints.Contains(c.Id)).Select(x => x.Id).ToListAsync(); + var result = await context.Set().Where(c => EF.MultipleParameters(ints).Contains(c.Id)).Select(x => x.Id).ToListAsync(); Assert.Equivalent(new[] { 2 }, result); } diff --git a/src/efcore/test/EFCore.Relational.Specification.Tests/Query/NorthwindWhereQueryRelationalTestBase.cs b/src/efcore/test/EFCore.Relational.Specification.Tests/Query/NorthwindWhereQueryRelationalTestBase.cs index 819f1a58c67..26b62b45334 100644 --- a/src/efcore/test/EFCore.Relational.Specification.Tests/Query/NorthwindWhereQueryRelationalTestBase.cs +++ b/src/efcore/test/EFCore.Relational.Specification.Tests/Query/NorthwindWhereQueryRelationalTestBase.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.EntityFrameworkCore.TestModels.Northwind; + namespace Microsoft.EntityFrameworkCore.Query; #nullable disable @@ -11,6 +13,18 @@ public abstract class NorthwindWhereQueryRelationalTestBase(TFixture f public override Task Where_bool_client_side_negated(bool async) => AssertTranslationFailed(() => base.Where_bool_client_side_negated(async)); + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual async Task EF_MultipleParameters_with_non_evaluatable_argument_throws(bool async) + { + var exception = await Assert.ThrowsAsync( + () => AssertQuery( + async, + ss => ss.Set().Where(c => c.Orders == EF.MultipleParameters(c.Orders)))); + + Assert.Equal(CoreStrings.EFMethodWithNonEvaluatableArgument("EF.MultipleParameters"), exception.Message); + } + protected override QueryAsserter CreateQueryAsserter(TFixture fixture) => new RelationalQueryAsserter( fixture, RewriteExpectedQueryExpression, RewriteServerQueryExpression); diff --git a/src/efcore/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs b/src/efcore/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs index 76b0ad64190..a3256aa31b7 100644 --- a/src/efcore/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs +++ b/src/efcore/test/EFCore.Specification.Tests/Query/NorthwindWhereQueryTestBase.cs @@ -2082,7 +2082,7 @@ public virtual async Task EF_Constant_with_non_evaluatable_argument_throws(bool async, ss => ss.Set().Where(c => c.CustomerID == EF.Constant(c.CustomerID)))); - Assert.Equal(CoreStrings.EFConstantWithNonEvaluatableArgument, exception.Message); + Assert.Equal(CoreStrings.EFMethodWithNonEvaluatableArgument("EF.Constant"), exception.Message); } [ConditionalTheory] @@ -2129,7 +2129,7 @@ public virtual async Task EF_Parameter_with_non_evaluatable_argument_throws(bool async, ss => ss.Set().Where(c => c.CustomerID == EF.Parameter(c.CustomerID)))); - Assert.Equal(CoreStrings.EFParameterWithNonEvaluatableArgument, exception.Message); + Assert.Equal(CoreStrings.EFMethodWithNonEvaluatableArgument("EF.Parameter"), exception.Message); } private class EntityWithImplicitCast(int value) diff --git a/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs b/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs index cc0a312389c..d017fa4209d 100644 --- a/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs +++ b/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/AdHocMiscellaneousQuerySqlServerTest.cs @@ -19,7 +19,7 @@ public class AdHocMiscellaneousQuerySqlServerTest(NonSharedFixture fixture) : Ad protected override ITestStoreFactory TestStoreFactory => SqlServerTestStoreFactory.Instance; - protected override DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterizedCollectionMode parameterizedCollectionMode) + protected override DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterTranslationMode parameterizedCollectionMode) { new SqlServerDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); diff --git a/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs b/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs index 3016f7c7b93..b7b86e420bc 100644 --- a/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs +++ b/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqlServerTest.cs @@ -10,7 +10,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class NonSharedPrimitiveCollectionsQuerySqlServerTest(NonSharedFixture fixture) : NonSharedPrimitiveCollectionsQueryRelationalTestBase(fixture) { - protected override DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterizedCollectionMode parameterizedCollectionMode) + protected override DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterTranslationMode parameterizedCollectionMode) { new SqlServerDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); @@ -785,12 +785,16 @@ FROM [TestEntityWithOwned] AS [t] """); } - public override async Task Parameter_collection_Count_with_column_predicate_with_default_constants() + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) { - await base.Parameter_collection_Count_with_column_predicate_with_default_constants(); + await base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode); - AssertSql( - """ + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ SELECT [t].[Id] FROM [TestEntity] AS [t] WHERE ( @@ -798,43 +802,68 @@ SELECT COUNT(*) FROM (VALUES (2), (999)) AS [i]([Value]) WHERE [i].[Value] > [t].[Id]) = 1 """); - } + break; + } - public override async Task Parameter_collection_Contains_with_default_constants() - { - await base.Parameter_collection_Contains_with_default_constants(); + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ids='[2,999]' (Size = 4000) - AssertSql( - """ SELECT [t].[Id] FROM [TestEntity] AS [t] -WHERE [t].[Id] IN (2, 999) +WHERE ( + SELECT COUNT(*) + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [t].[Id]) = 1 """); - } - - public override async Task Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter() - { - await base.Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter(); + break; + } - AssertSql( - """ -@ids='[2,999]' (Size = 4000) + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ids1='2' +@ids2='999' SELECT [t].[Id] FROM [TestEntity] AS [t] WHERE ( SELECT COUNT(*) - FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] - WHERE [i].[value] > [t].[Id]) = 1 + FROM (VALUES (@ids1), (@ids2)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 """); + break; + } + + default: + throw new NotImplementedException(); + } } - public override async Task Parameter_collection_Contains_with_default_constants_EF_Parameter() + public override async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) { - await base.Parameter_collection_Contains_with_default_constants_EF_Parameter(); + await base.Parameter_collection_Contains_with_default_mode(mode); - AssertSql( - """ + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (2, 999) +"""); + break; + } + + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ @ints='[2,999]' (Size = 4000) SELECT [t].[Id] @@ -844,72 +873,92 @@ SELECT [i].[value] FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] ) """); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT [t].[Id] +FROM [TestEntity] AS [t] +WHERE [t].[Id] IN (@ints1, @ints2) +"""); + break; + } + + default: + throw new NotImplementedException(); + } } - public override async Task Parameter_collection_Count_with_column_predicate_with_default_parameter() + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) { - await base.Parameter_collection_Count_with_column_predicate_with_default_parameter(); + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(mode); AssertSql( """ -@ids='[2,999]' (Size = 4000) - SELECT [t].[Id] FROM [TestEntity] AS [t] WHERE ( SELECT COUNT(*) - FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] - WHERE [i].[value] > [t].[Id]) = 1 + FROM (VALUES (2), (999)) AS [i]([Value]) + WHERE [i].[Value] > [t].[Id]) = 1 """); } - public override async Task Parameter_collection_Contains_with_default_parameter() + public override async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) { - await base.Parameter_collection_Contains_with_default_parameter(); + await base.Parameter_collection_Contains_with_default_mode_EF_Constant(mode); AssertSql( """ -@ints='[2,999]' (Size = 4000) - SELECT [t].[Id] FROM [TestEntity] AS [t] -WHERE [t].[Id] IN ( - SELECT [i].[value] - FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] -) +WHERE [t].[Id] IN (2, 999) """); } - public override async Task Parameter_collection_Count_with_column_predicate_with_default_parameter_EF_Constant() + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(ParameterTranslationMode mode) { - await base.Parameter_collection_Count_with_column_predicate_with_default_parameter_EF_Constant(); + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(mode); AssertSql( """ +@ids='[2,999]' (Size = 4000) + SELECT [t].[Id] FROM [TestEntity] AS [t] WHERE ( SELECT COUNT(*) - FROM (VALUES (2), (999)) AS [i]([Value]) - WHERE [i].[Value] > [t].[Id]) = 1 + FROM OPENJSON(@ids) WITH ([value] int '$') AS [i] + WHERE [i].[value] > [t].[Id]) = 1 """); } - public override async Task Parameter_collection_Contains_with_default_parameter_EF_Constant() + public override async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) { - await base.Parameter_collection_Contains_with_default_parameter_EF_Constant(); + await base.Parameter_collection_Contains_with_default_mode_EF_Parameter(mode); AssertSql( """ +@ints='[2,999]' (Size = 4000) + SELECT [t].[Id] FROM [TestEntity] AS [t] -WHERE [t].[Id] IN (2, 999) +WHERE [t].[Id] IN ( + SELECT [i].[value] + FROM OPENJSON(@ints) WITH ([value] int '$') AS [i] +) """); } - public override async Task Parameter_collection_Count_with_column_predicate_with_default_multiple_parameters() + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) { - await base.Parameter_collection_Count_with_column_predicate_with_default_multiple_parameters(); + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(mode); AssertSql( """ @@ -925,9 +974,9 @@ SELECT COUNT(*) """); } - public override async Task Parameter_collection_Contains_with_default_multiple_parameters() + public override async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) { - await base.Parameter_collection_Contains_with_default_multiple_parameters(); + await base.Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(mode); AssertSql( """ diff --git a/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs b/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs index f0f1f20ff23..bb81e7cd85e 100644 --- a/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs +++ b/src/efcore/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindWhereQuerySqlServerTest.cs @@ -2970,6 +2970,13 @@ FROM [Orders] AS [o] """); } + public override async Task EF_MultipleParameters_with_non_evaluatable_argument_throws(bool async) + { + await base.EF_MultipleParameters_with_non_evaluatable_argument_throws(async); + + AssertSql(); + } + #region Evaluation order of operators public override async Task Take_and_Where_evaluation_order(bool async) diff --git a/src/efcore/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs b/src/efcore/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs index e878daf1ff8..f80084d99e5 100644 --- a/src/efcore/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs +++ b/src/efcore/test/EFCore.Sqlite.FunctionalTests/Query/AdHocMiscellaneousQuerySqliteTest.cs @@ -10,7 +10,7 @@ public class AdHocMiscellaneousQuerySqliteTest(NonSharedFixture fixture) : AdHoc protected override ITestStoreFactory TestStoreFactory => SqliteTestStoreFactory.Instance; - protected override DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterizedCollectionMode parameterizedCollectionMode) + protected override DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterTranslationMode parameterizedCollectionMode) { new SqliteDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); diff --git a/src/efcore/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs b/src/efcore/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs index fbddf89fa4f..2f0eca42149 100644 --- a/src/efcore/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs +++ b/src/efcore/test/EFCore.Sqlite.FunctionalTests/Query/NonSharedPrimitiveCollectionsQuerySqliteTest.cs @@ -7,7 +7,7 @@ namespace Microsoft.EntityFrameworkCore.Query; public class NonSharedPrimitiveCollectionsQuerySqliteTest(NonSharedFixture fixture) : NonSharedPrimitiveCollectionsQueryRelationalTestBase(fixture) { - protected override DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterizedCollectionMode parameterizedCollectionMode) + protected override DbContextOptionsBuilder SetParameterizedCollectionMode(DbContextOptionsBuilder optionsBuilder, ParameterTranslationMode parameterizedCollectionMode) { new SqliteDbContextOptionsBuilder(optionsBuilder).UseParameterizedCollectionMode(parameterizedCollectionMode); @@ -329,12 +329,16 @@ LIMIT 2 """); } - public override async Task Parameter_collection_Count_with_column_predicate_with_default_constants() + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode(ParameterTranslationMode mode) { - await base.Parameter_collection_Count_with_column_predicate_with_default_constants(); - - AssertSql( - """ + await base.Parameter_collection_Count_with_column_predicate_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ SELECT "t"."Id" FROM "TestEntity" AS "t" WHERE ( @@ -342,43 +346,68 @@ SELECT COUNT(*) FROM (SELECT 2 AS "Value" UNION ALL VALUES (999)) AS "i" WHERE "i"."Value" > "t"."Id") = 1 """); - } + break; + } - public override async Task Parameter_collection_Contains_with_default_constants() - { - await base.Parameter_collection_Contains_with_default_constants(); + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ +@ids='[2,999]' (Size = 7) - AssertSql( - """ SELECT "t"."Id" FROM "TestEntity" AS "t" -WHERE "t"."Id" IN (2, 999) +WHERE ( + SELECT COUNT(*) + FROM json_each(@ids) AS "i" + WHERE "i"."value" > "t"."Id") = 1 """); - } - - public override async Task Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter() - { - await base.Parameter_collection_Count_with_column_predicate_with_default_constants_EF_Parameter(); + break; + } - AssertSql( - """ -@ids='[2,999]' (Size = 7) + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ids1='2' +@ids2='999' SELECT "t"."Id" FROM "TestEntity" AS "t" WHERE ( SELECT COUNT(*) - FROM json_each(@ids) AS "i" - WHERE "i"."value" > "t"."Id") = 1 + FROM (SELECT @ids1 AS "Value" UNION ALL VALUES (@ids2)) AS "i" + WHERE "i"."Value" > "t"."Id") = 1 """); + break; + } + + default: + throw new NotImplementedException(); + } } - public override async Task Parameter_collection_Contains_with_default_constants_EF_Parameter() + public override async Task Parameter_collection_Contains_with_default_mode(ParameterTranslationMode mode) { - await base.Parameter_collection_Contains_with_default_constants_EF_Parameter(); + await base.Parameter_collection_Contains_with_default_mode(mode); + + switch (mode) + { + case ParameterTranslationMode.Constant: + { + AssertSql( + """ +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN (2, 999) +"""); + break; + } - AssertSql( - """ + case ParameterTranslationMode.Parameter: + { + AssertSql( + """ @ints='[2,999]' (Size = 7) SELECT "t"."Id" @@ -388,72 +417,92 @@ public override async Task Parameter_collection_Contains_with_default_constants_ FROM json_each(@ints) AS "i" ) """); + break; + } + + case ParameterTranslationMode.MultipleParameters: + { + AssertSql( + """ +@ints1='2' +@ints2='999' + +SELECT "t"."Id" +FROM "TestEntity" AS "t" +WHERE "t"."Id" IN (@ints1, @ints2) +"""); + break; + } + + default: + throw new NotImplementedException(); + } } - public override async Task Parameter_collection_Count_with_column_predicate_with_default_parameter() + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(ParameterTranslationMode mode) { - await base.Parameter_collection_Count_with_column_predicate_with_default_parameter(); + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Constant(mode); AssertSql( """ -@ids='[2,999]' (Size = 7) - SELECT "t"."Id" FROM "TestEntity" AS "t" WHERE ( SELECT COUNT(*) - FROM json_each(@ids) AS "i" - WHERE "i"."value" > "t"."Id") = 1 + FROM (SELECT 2 AS "Value" UNION ALL VALUES (999)) AS "i" + WHERE "i"."Value" > "t"."Id") = 1 """); } - public override async Task Parameter_collection_Contains_with_default_parameter() + public override async Task Parameter_collection_Contains_with_default_mode_EF_Constant(ParameterTranslationMode mode) { - await base.Parameter_collection_Contains_with_default_parameter(); + await base.Parameter_collection_Contains_with_default_mode_EF_Constant(mode); AssertSql( """ -@ints='[2,999]' (Size = 7) - SELECT "t"."Id" FROM "TestEntity" AS "t" -WHERE "t"."Id" IN ( - SELECT "i"."value" - FROM json_each(@ints) AS "i" -) +WHERE "t"."Id" IN (2, 999) """); } - public override async Task Parameter_collection_Count_with_column_predicate_with_default_parameter_EF_Constant() + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(ParameterTranslationMode mode) { - await base.Parameter_collection_Count_with_column_predicate_with_default_parameter_EF_Constant(); + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_Parameter(mode); AssertSql( """ +@ids='[2,999]' (Size = 7) + SELECT "t"."Id" FROM "TestEntity" AS "t" WHERE ( SELECT COUNT(*) - FROM (SELECT 2 AS "Value" UNION ALL VALUES (999)) AS "i" - WHERE "i"."Value" > "t"."Id") = 1 + FROM json_each(@ids) AS "i" + WHERE "i"."value" > "t"."Id") = 1 """); } - public override async Task Parameter_collection_Contains_with_default_parameter_EF_Constant() + public override async Task Parameter_collection_Contains_with_default_mode_EF_Parameter(ParameterTranslationMode mode) { - await base.Parameter_collection_Contains_with_default_parameter_EF_Constant(); + await base.Parameter_collection_Contains_with_default_mode_EF_Parameter(mode); AssertSql( """ +@ints='[2,999]' (Size = 7) + SELECT "t"."Id" FROM "TestEntity" AS "t" -WHERE "t"."Id" IN (2, 999) +WHERE "t"."Id" IN ( + SELECT "i"."value" + FROM json_each(@ints) AS "i" +) """); } - public override async Task Parameter_collection_Count_with_column_predicate_with_default_multiple_parameters() + public override async Task Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) { - await base.Parameter_collection_Count_with_column_predicate_with_default_multiple_parameters(); + await base.Parameter_collection_Count_with_column_predicate_with_default_mode_EF_MultipleParameters(mode); AssertSql( """ @@ -469,9 +518,9 @@ SELECT COUNT(*) """); } - public override async Task Parameter_collection_Contains_with_default_multiple_parameters() + public override async Task Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(ParameterTranslationMode mode) { - await base.Parameter_collection_Contains_with_default_multiple_parameters(); + await base.Parameter_collection_Contains_with_default_mode_EF_MultipleParameters(mode); AssertSql( """ diff --git a/src/msbuild/.vsts-dotnet.yml b/src/msbuild/.vsts-dotnet.yml index af1ac148d7a..24dc1e31830 100644 --- a/src/msbuild/.vsts-dotnet.yml +++ b/src/msbuild/.vsts-dotnet.yml @@ -16,6 +16,10 @@ parameters: displayName: Optional OptProfDrop Override type: string default: 'default' +- name: EnableOptProf + displayName: Enable OptProf data collection for this build + type: boolean + default: true - name: requireDefaultChannelsEnabled displayName: Require Default Channels type: boolean @@ -39,6 +43,10 @@ variables: value: ${{parameters.OptProfDropName}} - name: SourceBranch value: '' + # Override SkipApplyOptimizationData to true when disabling OptProf data collection + - ${{ if eq(parameters.EnableOptProf, false) }}: + - name: SkipApplyOptimizationData + value: true - ${{ if and(not(startsWith(variables['Build.SourceBranch'], 'refs/heads/exp/')), not(startsWith(variables['Build.SourceBranch'], 'refs/heads/perf/'))) }}: - name: requireDefaultChannels value: ${{ parameters.requireDefaultChannelsEnabled }} @@ -172,6 +180,7 @@ extends: AccessToken: '$(System.AccessToken)' feedSource: 'https://devdiv.pkgs.visualstudio.com/DefaultCollection/_packaging/MicroBuildToolset/nuget/v3/index.json' displayName: 'Install OptProf Plugin' + condition: and(succeeded(), ${{ parameters.EnableOptProf }}) # Required by MicroBuildBuildVSBootstrapper - task: MicroBuildSwixPlugin@4 @@ -207,7 +216,7 @@ extends: toLowerCase: false usePat: true displayName: 'OptProf - Publish to Artifact Services - ProfilingInputs' - condition: succeeded() + condition: and(succeeded(), ${{ parameters.EnableOptProf }}) # Build VS bootstrapper # Generates $(Build.StagingDirectory)\MicroBuild\Output\BootstrapperInfo.json @@ -218,7 +227,7 @@ extends: manifests: $(VisualStudio.SetupManifestList) outputFolder: '$(Build.SourcesDirectory)\artifacts\VSSetup\$(BuildConfiguration)\Insertion' displayName: 'OptProf - Build VS bootstrapper' - condition: succeeded() + condition: and(succeeded(), ${{ parameters.EnableOptProf }}) # Publish run settings - task: PowerShell@2 @@ -230,7 +239,7 @@ extends: /p:BootstrapperInfoPath=$(Build.StagingDirectory)\MicroBuild\Output\BootstrapperInfo.json /p:VisualStudioIbcTrainingSettingsPath=$(Build.SourcesDirectory)\eng\config\OptProf.runsettings displayName: 'OptProf - Build IBC training settings' - condition: succeeded() + condition: and(succeeded(), ${{ parameters.EnableOptProf }}) # Publish bootstrapper info - task: 1ES.PublishBuildArtifacts@1 @@ -239,7 +248,7 @@ extends: ArtifactName: MicroBuildOutputs ArtifactType: Container displayName: 'OptProf - Publish Artifact: MicroBuildOutputs' - condition: succeeded() + condition: and(succeeded(), ${{ parameters.EnableOptProf }}) - task: 1ES.PublishBuildArtifacts@1 displayName: 'Publish Artifact: logs' @@ -301,7 +310,7 @@ extends: displayName: Tag build as ready for optimization training inputs: tags: 'ready-for-training' - condition: succeeded() + condition: and(succeeded(), ${{ parameters.EnableOptProf }}) - task: ms-vseng.MicroBuildTasks.521a94ea-9e68-468a-8167-6dcf361ea776.MicroBuildCleanup@1 displayName: Execute cleanup tasks diff --git a/src/msbuild/documentation/specs/build-nonexistent-projects-by-default.md b/src/msbuild/documentation/specs/build-nonexistent-projects-by-default.md new file mode 100644 index 00000000000..9f0c0774c46 --- /dev/null +++ b/src/msbuild/documentation/specs/build-nonexistent-projects-by-default.md @@ -0,0 +1,106 @@ +# BuildNonexistentProjectsByDefault Global Property + +## Summary + +The `_BuildNonexistentProjectsByDefault` global property enables MSBuild tasks to build in-memory or virtual projects by defaulting to `SkipNonexistentProjects=Build` behavior when the property is not explicitly specified. + +## Background and Motivation + +### Problem + +[File-based applications][file-based-apps] (such as `dotnet run file.cs`) create in-memory MSBuild projects without corresponding physical `.csproj` files on disk. When these projects use common targets that include MSBuild tasks referencing the current project (e.g., ``), the build fails because MSBuild cannot find the project file on disk, even though the project content is available in memory. + +This pattern is very common in .NET SDK targets, creating friction for file-based applications that need to reuse existing build logic. + +### Use Case Example + +Consider a file-based application that creates an in-memory project: + +```csharp +var xmlReader = XmlReader.Create(new StringReader(projectText)); +var projectRoot = ProjectRootElement.Create(xmlReader); +projectRoot.FullPath = Path.Join(Environment.CurrentDirectory, "test.csproj"); +// Project exists in memory but not on disk +``` + +When this project uses targets containing: +```xml + +``` + +The build fails with: +> MSB3202: The project file "test.csproj" was not found. + +## Solution + +### The `_BuildNonexistentProjectsByDefault` Property + +This internal global property provides an opt-in mechanism to change the default behavior of MSBuild tasks when `SkipNonexistentProjects` is not explicitly specified. + +**Property Name:** `_BuildNonexistentProjectsByDefault` +**Type:** Boolean +**Default:** `false` (when not set) +**Scope:** Global property only + +### Behavior + +When `_BuildNonexistentProjectsByDefault` is set to `true`: + +1. **MSBuild tasks** that don't explicitly specify `SkipNonexistentProjects` will default to `SkipNonexistentProjects="Build"` instead of `SkipNonexistentProjects="False"` +2. **In-memory projects** with a valid `FullPath` can be built even when no physical file exists on disk +3. **Existing explicit settings** are preserved - if `SkipNonexistentProjects` is explicitly set on the MSBuild task, that takes precedence + +### Implementation Details + +The property is checked in two MSBuild task implementations: + +1. **`src/Tasks/MSBuild.cs`** - The standard MSBuild task implementation +2. **`src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/MSBuild.cs`** - The backend intrinsic task implementation + +The logic follows this precedence order: + +1. If `SkipNonexistentProjects` is explicitly set on the MSBuild task → use that value +2. If `SkipNonexistentProjects` metadata is specified on the project item → use that value +3. If `_BuildNonexistentProjectsByDefault=true` is set globally → default to `Build` +4. Otherwise → default to `Error` (existing behavior) + +## Usage + +### File-based Applications + +File-based applications can set this property when building in-memory projects: + +```csharp +var project = ObjectModelHelpers.CreateInMemoryProject(projectContent); +project.SetGlobalProperty("_BuildNonexistentProjectsByDefault", "true"); +bool result = project.Build(); +``` + +### SDK Integration + +The .NET SDK will use this property to enable building file-based applications without workarounds when calling MSBuild tasks that reference the current project. + +## Breaking Changes + +**None.** This is an opt-in feature with an internal property name (prefixed with `_`). Existing behavior is preserved when the property is not set. + +## Alternatives Considered + +1. **Always allow building in-memory projects**: This would be a breaking change as it could mask legitimate errors when projects are missing. + +2. **Add a new MSBuild task parameter**: This would require modifying all existing targets to use the new parameter, creating compatibility issues. + +3. **Modify SkipNonexistentProjects default**: This would be a breaking change affecting all MSBuild usage. + +4. **Engine-level configuration**: More complex to implement and would require serialization across build nodes. + +The global property approach provides the needed functionality while maintaining backward compatibility and requiring minimal changes to the MSBuild task implementations. + +## Related Issues + +- [#12058](https://github.com/dotnet/msbuild/issues/12058) - MSBuild task should work on virtual projects +- [dotnet/sdk#49745](https://github.com/dotnet/sdk/pull/49745) - Remove MSBuild hacks for virtual project building +- [NuGet/Home#14148](https://github.com/NuGet/Home/issues/14148) - Related workaround requirements +- [File-based app spec][file-based-apps] - Motivating use-case + +[file-based-apps]: https://github.com/dotnet/sdk/blob/main/documentation/general/dotnet-run-file.md diff --git a/src/msbuild/eng/Packages.props b/src/msbuild/eng/Packages.props index 6817b951611..a5f52eecb45 100644 --- a/src/msbuild/eng/Packages.props +++ b/src/msbuild/eng/Packages.props @@ -10,6 +10,8 @@ + + diff --git a/src/msbuild/eng/Version.Details.xml b/src/msbuild/eng/Version.Details.xml index d8ed7db1959..d511ea7e779 100644 --- a/src/msbuild/eng/Version.Details.xml +++ b/src/msbuild/eng/Version.Details.xml @@ -112,21 +112,21 @@ - + https://github.com/dotnet/arcade - aea743edf7c9345cfdbdf9593756973baadc6b37 + 4e526204e83e615efe8eb5743be7fbccfa4e492a https://github.com/nuget/nuget.client eb38c4a6cccfce5ee9415da1a930fc6534194b2b - + https://github.com/dotnet/roslyn - 334d4c7ade78170d7b06448a2807627ddb96d742 + d3571ef089ef13c74ea786dce8ef615916a097cd - + https://github.com/dotnet/arcade - aea743edf7c9345cfdbdf9593756973baadc6b37 + 4e526204e83e615efe8eb5743be7fbccfa4e492a diff --git a/src/msbuild/eng/Versions.props b/src/msbuild/eng/Versions.props index 2631a1cb620..0826882f7da 100644 --- a/src/msbuild/eng/Versions.props +++ b/src/msbuild/eng/Versions.props @@ -79,10 +79,10 @@ $([System.Text.RegularExpressions.Regex]::Match($([System.IO.File]::ReadAllText('$(MSBuildThisFileDirectory)..\global.json')), '"dotnet": "([^"]*)"').Groups.get_Item(1)) - 4.2.0-1.22102.8 - 10.0.0-beta.25353.1 + 5.0.0-1.25277.114 + 10.0.0-beta.25358.3 6.15.0-preview.1.86 - 5.0.0-1.25358.1 + 5.0.0-1.25361.3 10.0.100-preview.6.25315.102 diff --git a/src/msbuild/global.json b/src/msbuild/global.json index 1a7cba33e66..c3fb763918e 100644 --- a/src/msbuild/global.json +++ b/src/msbuild/global.json @@ -15,6 +15,6 @@ "xcopy-msbuild": "17.13.0" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25353.1" + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25358.3" } } diff --git a/src/msbuild/src/Build.UnitTests/BackEnd/MSBuild_Tests.cs b/src/msbuild/src/Build.UnitTests/BackEnd/MSBuild_Tests.cs index 1922000b7c7..cefd001921f 100644 --- a/src/msbuild/src/Build.UnitTests/BackEnd/MSBuild_Tests.cs +++ b/src/msbuild/src/Build.UnitTests/BackEnd/MSBuild_Tests.cs @@ -1895,5 +1895,107 @@ public void ProjectFileWithoutNamespaceBuilds() File.Delete(projectFile2); } } + + [Fact] + public void InMemoryProject_Build() + { + Project project = ObjectModelHelpers.CreateInMemoryProject(""" + + + + + + + + + """); + + var logger = new MockLogger(); + bool result = project.Build(logger); + _testOutput.WriteLine(logger.FullLog); + Assert.True(result); + logger.AssertLogContains("test message from other"); + } + + [Fact] + public void InMemoryProject_Error() + { + Project project = ObjectModelHelpers.CreateInMemoryProject(""" + + + + + + + + + """); + + var logger = new MockLogger(); + bool result = project.Build(logger); + _testOutput.WriteLine(logger.FullLog); + Assert.False(result); + logger.AssertLogDoesntContain("test message from other"); + logger.AssertLogContains("MSB3202"); // error MSB3202: The project file was not found. + } + + /// + /// This is used by file-based apps (dotnet run file.cs) which use in-memory projects + /// and want to support existing targets which often invoke the MSBuild task on the current project. + /// + [Fact] + public void InMemoryProject_BuildByDefault() + { + Project project = ObjectModelHelpers.CreateInMemoryProject(""" + + + + + + + + + """); + + project.SetGlobalProperty(PropertyNames.BuildNonexistentProjectsByDefault, bool.TrueString); + + var logger = new MockLogger(); + bool result = project.Build(logger); + _testOutput.WriteLine(logger.FullLog); + Assert.True(result); + logger.AssertLogContains("test message from other"); + } + + [Theory] + [InlineData(null)] + [InlineData(false)] + [InlineData(true)] + public void NonExistentProject(bool? buildNonexistentProjectsByDefault) + { + Project project = ObjectModelHelpers.CreateInMemoryProject(""" + + + + + + + + + """); + + if (buildNonexistentProjectsByDefault is { } b) + { + project.SetGlobalProperty(PropertyNames.BuildNonexistentProjectsByDefault, b.ToString()); + } + + var logger = new MockLogger(); + bool result = project.Build(logger); + _testOutput.WriteLine(logger.FullLog); + Assert.False(result); + logger.AssertLogDoesntContain("test message from other"); + logger.AssertLogContains(buildNonexistentProjectsByDefault == true + ? "MSB4025" // error MSB4025: The project file could not be loaded. + : "MSB3202"); // error MSB3202: The project file was not found. + } } } diff --git a/src/msbuild/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs b/src/msbuild/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs index d3c1c9820db..46ec826e287 100644 --- a/src/msbuild/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs +++ b/src/msbuild/src/Build/BackEnd/Components/Communications/NodeProviderOutOfProcBase.cs @@ -161,29 +161,22 @@ protected void ShutdownAllNodes(bool nodeReuse, NodeContextTerminateDelegate ter int timeout = 30; // Attempt to connect to the process with the handshake without low priority. - using Stream nodeStream = TryConnectToProcess(nodeProcess.Id, timeout, NodeProviderOutOfProc.GetHandshake(nodeReuse, false)); - if (nodeStream != null) - { - ShutdownNode(terminateNode, factory, nodeProcess, nodeStream); - } - else + Stream nodeStream = TryConnectToProcess(nodeProcess.Id, timeout, NodeProviderOutOfProc.GetHandshake(nodeReuse, false)); + + if (nodeStream == null) { // If we couldn't connect attempt to connect to the process with the handshake including low priority. - using Stream lowPriorityConnection = TryConnectToProcess(nodeProcess.Id, timeout, NodeProviderOutOfProc.GetHandshake(nodeReuse, true)); - - if (lowPriorityConnection != null) - { - ShutdownNode(terminateNode, factory, nodeProcess, lowPriorityConnection); - } + nodeStream = TryConnectToProcess(nodeProcess.Id, timeout, NodeProviderOutOfProc.GetHandshake(nodeReuse, true)); } - } - static void ShutdownNode(NodeContextTerminateDelegate terminateNode, INodePacketFactory factory, Process nodeProcess, Stream nodeStream) - { - // If we're able to connect to such a process, send a packet requesting its termination - CommunicationsUtilities.Trace("Shutting down node with pid = {0}", nodeProcess.Id); - NodeContext nodeContext = new NodeContext(0, nodeProcess, nodeStream, factory, terminateNode); - nodeContext.SendData(new NodeBuildComplete(false /* no node reuse */)); + if (nodeStream != null) + { + // If we're able to connect to such a process, send a packet requesting its termination + CommunicationsUtilities.Trace("Shutting down node with pid = {0}", nodeProcess.Id); + NodeContext nodeContext = new NodeContext(0, nodeProcess, nodeStream, factory, terminateNode); + nodeContext.SendData(new NodeBuildComplete(false /* no node reuse */)); + nodeStream.Dispose(); + } } } @@ -607,14 +600,19 @@ private enum ExitPacketState private readonly NodeContextTerminateDelegate _terminateDelegate; /// - /// A task representing the work to consume enqueued packets. + /// A dedicated thread to consume enqueued packets. + /// + private readonly Thread _drainPacketQueueThread; + + /// + /// Used to signal the consuming thread that a packet has been enqueued; /// - private readonly Task _packetWriteDrainTask; + private readonly AutoResetEvent _packetEnqueued; /// - /// Used to signal the consuming task that a packet has been enqueued. + /// Used to signal that the exit packet has been sent and we no longer need to wait for the queue to drain. /// - private readonly SemaphoreSlim _packetEnqueued; + private readonly CancellationTokenSource _packetQueueDrainDelayCancellation; /// /// Tracks the state of the packet sent to terminate the node. @@ -650,9 +648,13 @@ public NodeContext(int nodeId, Process process, #endif _packetWriteQueue = new ConcurrentQueue(); - _packetEnqueued = new SemaphoreSlim(0, 1); + _packetEnqueued = new AutoResetEvent(false); + _packetQueueDrainDelayCancellation = new CancellationTokenSource(); - _packetWriteDrainTask = DrainPacketQueue(); + // specify the smallest stack size - 64kb + _drainPacketQueueThread = new Thread(DrainPacketQueue, 64 * 1024); + _drainPacketQueueThread.IsBackground = true; + _drainPacketQueueThread.Start(this); } /// @@ -758,35 +760,30 @@ public void SendData(INodePacket packet) { _exitPacketState = ExitPacketState.ExitPacketQueued; } - _packetWriteQueue.Enqueue(packet); - - if (_packetEnqueued.CurrentCount == 0) - { - // If the semaphore is not already signaled, signal it to wake up the draining task. - _packetEnqueued.Release(); - } + _packetEnqueued.Set(); } /// - /// Use a threadpool thread to drain the queue and be careful not to block it where possible. + /// We use a dedicated thread to avoid blocking a threadpool thread. /// /// Usually there'll be a single packet in the queue, but sometimes /// a burst of SendData comes in, with 10-20 packets scheduled. - private async Task DrainPacketQueue() + private void DrainPacketQueue(object state) { - MemoryStream writeStream = _writeBufferMemoryStream; - Stream serverToClientStream = _pipeStream; - ITranslator writeTranslator = _writeTranslator; + NodeContext context = (NodeContext)state; + MemoryStream writeStream = context._writeBufferMemoryStream; + Stream serverToClientStream = context._pipeStream; while (true) { - await _packetEnqueued.WaitAsync(); - while (_packetWriteQueue.TryDequeue(out INodePacket packet)) + context._packetEnqueued.WaitOne(); + while (context._packetWriteQueue.TryDequeue(out INodePacket packet)) { // clear the buffer but keep the underlying capacity to avoid reallocations writeStream.SetLength(0); + ITranslator writeTranslator = context._writeTranslator; try { writeStream.WriteByte((byte)packet.Type); @@ -806,29 +803,22 @@ private async Task DrainPacketQueue() for (int i = 0; i < writeStreamLength; i += MaxPacketWriteSize) { int lengthToWrite = Math.Min(writeStreamLength - i, MaxPacketWriteSize); -#if NET - await serverToClientStream.WriteAsync(writeStreamBuffer.AsMemory(i, lengthToWrite)); -#else - await serverToClientStream.WriteAsync(writeStreamBuffer, i, lengthToWrite); -#endif + + serverToClientStream.Write(writeStreamBuffer, i, lengthToWrite); } if (IsExitPacket(packet)) { - _exitPacketState = ExitPacketState.ExitPacketSent; + context._exitPacketState = ExitPacketState.ExitPacketSent; + context._packetQueueDrainDelayCancellation.Cancel(); return; } - - if (packet is NodeBuildComplete) - { - return; - } } catch (IOException e) { // Do nothing here because any exception will be caught by the async read handler - CommunicationsUtilities.Trace(_nodeId, "EXCEPTION in SendData: {0}", e); + CommunicationsUtilities.Trace(context._nodeId, "EXCEPTION in SendData: {0}", e); } catch (ObjectDisposedException) // This happens if a child dies unexpectedly { @@ -860,7 +850,6 @@ private static void WriteInt32(MemoryStream stream, int value) private void Close() { _pipeStream.Dispose(); - _packetEnqueued.Dispose(); _terminateDelegate(_nodeId); } @@ -874,16 +863,14 @@ public async Task WaitForExitAsync(ILoggingService loggingService) // Wait up to 100ms until all remaining packets are sent. // We don't need to wait long, just long enough for the Task to start running on the ThreadPool. #if NET - await _packetWriteDrainTask.WaitAsync(TimeSpan.FromMilliseconds(100)).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); + await Task.Delay(100, _packetQueueDrainDelayCancellation.Token).ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing); #else - using (var cts = new CancellationTokenSource(100)) - { - await Task.WhenAny(_packetWriteDrainTask, Task.Delay(100, cts.Token)); - cts.Cancel(); - } + await Task.WhenAny(Task.Delay(100, _packetQueueDrainDelayCancellation.Token)); #endif } + _packetQueueDrainDelayCancellation?.Dispose(); + if (_exitPacketState == ExitPacketState.ExitPacketSent) { CommunicationsUtilities.Trace("Waiting for node with pid = {0} to exit", _process.Id); diff --git a/src/msbuild/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/MSBuild.cs b/src/msbuild/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/MSBuild.cs index ac3e5aab535..8142e3266d4 100644 --- a/src/msbuild/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/MSBuild.cs +++ b/src/msbuild/src/Build/BackEnd/Components/RequestBuilder/IntrinsicTasks/MSBuild.cs @@ -330,6 +330,12 @@ public async Task ExecuteInternal() { skipNonExistProjects = behavior; } + else if (BuildEngine is IBuildEngine6 buildEngine6 && buildEngine6.GetGlobalProperties() + .TryGetValue(PropertyNames.BuildNonexistentProjectsByDefault, out var buildNonexistentProjectsByDefault) && + ConversionUtilities.ConvertStringToBool(buildNonexistentProjectsByDefault)) + { + skipNonExistProjects = SkipNonExistentProjectsBehavior.Build; + } else { skipNonExistProjects = SkipNonExistentProjectsBehavior.Error; diff --git a/src/msbuild/src/Build/BackEnd/Components/Scheduler/Scheduler.cs b/src/msbuild/src/Build/BackEnd/Components/Scheduler/Scheduler.cs index a8cc5967168..0598341fa5b 100644 --- a/src/msbuild/src/Build/BackEnd/Components/Scheduler/Scheduler.cs +++ b/src/msbuild/src/Build/BackEnd/Components/Scheduler/Scheduler.cs @@ -185,6 +185,13 @@ internal bool ForceAffinityOutOfProc /// private string _noLoggingCompletedSubmissionDetails; + /// + /// Static variable to track whether this is the first write to the debug dump file. + /// If true, indicates that a header should be written to the file. + /// After the first write, this is set to false to prevent writing the header in subsequent writes. + /// + private static bool _debugDumpIsFirstWrite = true; + #pragma warning restore IDE0052 // Remove unread private members #pragma warning restore CS0414 // The field is assigned but its value is never used @@ -1713,7 +1720,7 @@ private void HandleRequestBlockedByNewRequests(SchedulableRequest parentRequest, } int nodeForResults = (parentRequest == null) ? InvalidNodeId : parentRequest.AssignedNode; - TraceScheduler("Received request {0} (node request {1}) with parent {2} from node {3}", request.GlobalRequestId, request.NodeRequestId, request.ParentGlobalRequestId, nodeForResults); + TraceScheduler("Received request {0} (node request {1}) with parent {2} from node {3} for project {4} with targets {5}", request.GlobalRequestId, request.NodeRequestId, request.ParentGlobalRequestId, nodeForResults, _configCache![request.ConfigurationId].ProjectFullPath, request.Targets.Count == 0 ? "default" : string.Join(";", request.Targets)); // First, determine if we have already built this request and have results for it. If we do, we prepare the responses for it // directly here. We COULD simply report these as blocking the parent request and let the scheduler pick them up later when the parent @@ -2625,8 +2632,25 @@ private void DumpSchedulerState() try { FileUtilities.EnsureDirectoryExists(_debugDumpPath); + + bool shouldWriteHeader = _debugDumpIsFirstWrite; + if (shouldWriteHeader) + { + shouldWriteHeader = !File.Exists(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), EnvironmentUtilities.CurrentProcessId)); + _debugDumpIsFirstWrite = false; + } using StreamWriter file = FileUtilities.OpenWrite(string.Format(CultureInfo.CurrentCulture, Path.Combine(_debugDumpPath, "SchedulerState_{0}.txt"), EnvironmentUtilities.CurrentProcessId), append: true); + + if (shouldWriteHeader) + { + file.WriteLine("SchedulerState Log Symbols:"); + file.WriteLine("! - Blocked request: A build request waiting for dependencies or resources."); + file.WriteLine("> - Executing request: A build request currently being processed by a node."); + file.WriteLine("------------------------------------------------"); + file.WriteLine(); + } + file.WriteLine("Scheduler state at timestamp {0}:", _schedulingData.EventTime.Ticks); file.WriteLine("------------------------------------------------"); diff --git a/src/msbuild/src/Build/Logging/TerminalLogger/Terminal.cs b/src/msbuild/src/Build/Logging/TerminalLogger/Terminal.cs index 01a3065cd93..fd9133a2fa9 100644 --- a/src/msbuild/src/Build/Logging/TerminalLogger/Terminal.cs +++ b/src/msbuild/src/Build/Logging/TerminalLogger/Terminal.cs @@ -36,7 +36,15 @@ internal sealed class Terminal : ITerminal private const int BigUnknownDimension = 2 << 23; - /// + /// + /// Gets the height of the of the underlying . + /// If the , returns a large number to indicate that the height is unknown. + /// If the is zero, returns a large number to indicate that the height is unknown/synthetic. + /// + /// + /// We also try to prevent TerminalLogger from being used in scenarios where the console buffer is not set up correctly, such as in some CI environments, + /// but a user can always force the use of TerminalLogger so we must be defensive in the implementation. + /// public int Height { get @@ -46,11 +54,19 @@ public int Height return BigUnknownDimension; } - return Console.BufferHeight; + return Console.BufferHeight == 0 ? BigUnknownDimension : Console.BufferHeight; } } - /// + /// + /// Gets the width of the of the underlying . + /// If the , returns a large number to indicate that the width is unknown. + /// If the is zero, returns a large number to indicate that the width is unknown/synthetic. + /// + /// + /// We also try to prevent TerminalLogger from being used in scenarios where the console buffer is not set up correctly, such as in some CI environments, + /// but a user can always force the use of TerminalLogger so we must be defensive in the implementation. + /// public int Width { get @@ -60,7 +76,7 @@ public int Width return BigUnknownDimension; } - return Console.BufferWidth; + return Console.BufferWidth == 0 ? BigUnknownDimension : Console.BufferWidth; } } @@ -209,7 +225,7 @@ public void Dispose() { // In some terminal emulators setting back the previous console output encoding fails. // See https://github.com/dotnet/msbuild/issues/9662. - // We do not want to throw an exception if it happens, since it is a non-essentual failure in the logger. + // We do not want to throw an exception if it happens, since it is a non-essential failure in the logger. } } } diff --git a/src/msbuild/src/Build/Logging/TerminalLogger/TerminalLogger.cs b/src/msbuild/src/Build/Logging/TerminalLogger/TerminalLogger.cs index deb07b5405c..4bfb2299932 100644 --- a/src/msbuild/src/Build/Logging/TerminalLogger/TerminalLogger.cs +++ b/src/msbuild/src/Build/Logging/TerminalLogger/TerminalLogger.cs @@ -885,12 +885,15 @@ private void MessageRaised(object sender, BuildMessageEventArgs e) { if (e.Code == "NETSDK1057" && !_loggedPreviewMessage) { - // The SDK will log the high-pri "not-a-warning" message NETSDK1057 - // when it's a preview version up to MaxCPUCount times, but that's - // an implementation detail--the user cares about at most one. - - RenderImmediateMessage(message); - _loggedPreviewMessage = true; + // ensure we only log the preview message once for the entire build. + if (!_loggedPreviewMessage) + { + // The SDK will log the high-pri "not-a-warning" message NETSDK1057 + // when it's a preview version up to MaxCPUCount times, but that's + // an implementation detail--the user cares about at most one. + RenderImmediateMessage(FormatSimpleMessageWithoutFileData(e, DoubleIndentation)); + _loggedPreviewMessage = true; + } return; } } @@ -1223,6 +1226,29 @@ private string FormatWarningMessage(BuildWarningEventArgs e, string indent) indent); } + /// + /// Renders message with just code/category/message data. + /// No file data is included. This can be used for immediate/one-time + /// messages that lack a specific project context, such as the .NET + /// SDK's 'preview version' message, while not removing the code. + /// + private string FormatSimpleMessageWithoutFileData(BuildMessageEventArgs e, string indent) + { + return FormatEventMessage( + category: AnsiCodes.Colorize("info", TerminalColor.Default), + subcategory: null, + message: e.Message, + code: AnsiCodes.Colorize(e.Code, TerminalColor.Default), + file: null, + lineNumber: 0, + endLineNumber: 0, + columnNumber: 0, + endColumnNumber: 0, + indent, + requireFileAndLinePortion: false, + prependIndentation: true); + } + private string FormatErrorMessage(BuildErrorEventArgs e, string indent) { return FormatEventMessage( @@ -1240,7 +1266,7 @@ private string FormatErrorMessage(BuildErrorEventArgs e, string indent) private string FormatEventMessage( string category, - string subcategory, + string? subcategory, string? message, string code, string? file, @@ -1248,44 +1274,53 @@ private string FormatEventMessage( int endLineNumber, int columnNumber, int endColumnNumber, - string indent) + string indent, + bool requireFileAndLinePortion = true, + bool prependIndentation = false) { message ??= string.Empty; StringBuilder builder = new(128); - - if (string.IsNullOrEmpty(file)) + if (prependIndentation) { - builder.Append("MSBUILD : "); // Should not be localized. + builder.Append(indent); } - else - { - builder.Append(file); - if (lineNumber == 0) + if (requireFileAndLinePortion) + { + if (string.IsNullOrEmpty(file)) { - builder.Append(" : "); + builder.Append("MSBUILD : "); // Should not be localized. } else { - if (columnNumber == 0) + builder.Append(file); + + if (lineNumber == 0) { - builder.Append(endLineNumber == 0 ? - $"({lineNumber}): " : - $"({lineNumber}-{endLineNumber}): "); + builder.Append(" : "); } else { - if (endLineNumber == 0) + if (columnNumber == 0) { - builder.Append(endColumnNumber == 0 ? - $"({lineNumber},{columnNumber}): " : - $"({lineNumber},{columnNumber}-{endColumnNumber}): "); + builder.Append(endLineNumber == 0 ? + $"({lineNumber}): " : + $"({lineNumber}-{endLineNumber}): "); } else { - builder.Append(endColumnNumber == 0 ? - $"({lineNumber}-{endLineNumber},{columnNumber}): " : - $"({lineNumber},{columnNumber},{endLineNumber},{endColumnNumber}): "); + if (endLineNumber == 0) + { + builder.Append(endColumnNumber == 0 ? + $"({lineNumber},{columnNumber}): " : + $"({lineNumber},{columnNumber}-{endColumnNumber}): "); + } + else + { + builder.Append(endColumnNumber == 0 ? + $"({lineNumber}-{endLineNumber},{columnNumber}): " : + $"({lineNumber},{columnNumber},{endLineNumber},{endColumnNumber}): "); + } } } } diff --git a/src/msbuild/src/Build/Microsoft.Build.csproj b/src/msbuild/src/Build/Microsoft.Build.csproj index 7adeacbb321..0c9cd1c3da9 100644 --- a/src/msbuild/src/Build/Microsoft.Build.csproj +++ b/src/msbuild/src/Build/Microsoft.Build.csproj @@ -38,6 +38,8 @@ + + @@ -80,6 +82,9 @@ BackEnd\Components\RequestBuilder\IntrinsicTasks\CanonicalError.cs + + IConstrainedEqualityComparer.cs + BackEnd\Components\RequestBuilder\IntrinsicTasks\PropertyParser.cs @@ -121,9 +126,6 @@ BackEnd\Components\RequestBuilder\IntrinsicTasks\TaskLoggingHelperExtension.cs - - BuildCheck\Utilities\IsExternalInit.cs - @@ -378,6 +380,7 @@ Collections\CopyOnWriteDictionary.cs + diff --git a/src/msbuild/src/Framework/AssemblyUtilities.cs b/src/msbuild/src/Framework/AssemblyUtilities.cs index 5eb6e996a6e..6b21b7d22eb 100644 --- a/src/msbuild/src/Framework/AssemblyUtilities.cs +++ b/src/msbuild/src/Framework/AssemblyUtilities.cs @@ -10,15 +10,8 @@ using Microsoft.Build.Framework; #endif - -// Declare this to get init properties. See https://github.com/dotnet/roslyn/issues/45510#issuecomment-694977239 #nullable disable -namespace System.Runtime.CompilerServices -{ - internal static class IsExternalInit { } -} - namespace Microsoft.Build.Shared { /// diff --git a/src/msbuild/src/Framework/Microsoft.Build.Framework.csproj b/src/msbuild/src/Framework/Microsoft.Build.Framework.csproj index da61a612686..296bff029bd 100644 --- a/src/msbuild/src/Framework/Microsoft.Build.Framework.csproj +++ b/src/msbuild/src/Framework/Microsoft.Build.Framework.csproj @@ -15,7 +15,7 @@ - + @@ -29,8 +29,9 @@ - + + diff --git a/src/msbuild/src/Framework/NativeMethods.cs b/src/msbuild/src/Framework/NativeMethods.cs index 352723a6e53..3dece87f8a4 100644 --- a/src/msbuild/src/Framework/NativeMethods.cs +++ b/src/msbuild/src/Framework/NativeMethods.cs @@ -1593,6 +1593,13 @@ internal static (bool acceptAnsiColorCodes, bool outputIsScreen, uint? originalC return (acceptAnsiColorCodes: false, outputIsScreen: false, originalConsoleMode: null); } + if (Console.BufferHeight == 0 || Console.BufferWidth == 0) + { + // The current console doesn't have a valid buffer size, which means it is not a real console. let's default to not using TL + // in those scenarios. + return (acceptAnsiColorCodes: false, outputIsScreen: false, originalConsoleMode: null); + } + bool acceptAnsiColorCodes = false; bool outputIsScreen = false; uint? originalConsoleMode = null; diff --git a/src/msbuild/src/MSBuild/MSBuild.csproj b/src/msbuild/src/MSBuild/MSBuild.csproj index 8df57c447ab..686e78276ab 100644 --- a/src/msbuild/src/MSBuild/MSBuild.csproj +++ b/src/msbuild/src/MSBuild/MSBuild.csproj @@ -76,6 +76,9 @@ FileUtilitiesRegex.cs + + IConstrainedEqualityComparer.cs + RegisteredTaskObjectCacheBase.cs @@ -88,6 +91,7 @@ + diff --git a/src/msbuild/src/MSBuild/XMake.cs b/src/msbuild/src/MSBuild/XMake.cs index a2f925408b6..2239b55d156 100644 --- a/src/msbuild/src/MSBuild/XMake.cs +++ b/src/msbuild/src/MSBuild/XMake.cs @@ -2789,7 +2789,9 @@ private static bool ProcessCommandLineSwitches( verbosity = LoggerVerbosity.Diagnostic; } - if (originalVerbosity == LoggerVerbosity.Diagnostic) + // we don't want to write the MSBuild command line to the display because TL by intent is a + // highly-controlled visual experience and we don't want to clutter it with the command line switches. + if (originalVerbosity == LoggerVerbosity.Diagnostic && !useTerminalLogger) { string equivalentCommandLine = commandLineSwitches.GetEquivalentCommandLineExceptProjectFile(); Console.WriteLine($"{Path.Combine(s_exePath, s_exeName)} {equivalentCommandLine} {projectFile}"); diff --git a/src/msbuild/src/MSBuildTaskHost/MSBuildTaskHost.csproj b/src/msbuild/src/MSBuildTaskHost/MSBuildTaskHost.csproj index 5f812c4b7a6..83345b0c8ae 100644 --- a/src/msbuild/src/MSBuildTaskHost/MSBuildTaskHost.csproj +++ b/src/msbuild/src/MSBuildTaskHost/MSBuildTaskHost.csproj @@ -70,6 +70,7 @@ CopyOnWriteDictionary.cs + @@ -202,6 +203,7 @@ + @@ -220,8 +222,6 @@ - - diff --git a/src/msbuild/src/Framework/Polyfills/NullableAttributes.cs b/src/msbuild/src/MSBuildTaskHost/NullableAttributes.cs similarity index 97% rename from src/msbuild/src/Framework/Polyfills/NullableAttributes.cs rename to src/msbuild/src/MSBuildTaskHost/NullableAttributes.cs index b6698fce618..2c086ba5622 100644 --- a/src/msbuild/src/Framework/Polyfills/NullableAttributes.cs +++ b/src/msbuild/src/MSBuildTaskHost/NullableAttributes.cs @@ -3,6 +3,8 @@ // This was copied from https://github.com/dotnet/runtime/blob/39b9607807f29e48cae4652cd74735182b31182e/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/NullableAttributes.cs // and updated to have the scope of the attributes be internal. +// This file is used only by MSBuildTaskHost; other projects should get the polyfills from the +// Microsoft.CodeAnalysis.Contracts package, through the Microsoft.Build.Framework project. #nullable disable diff --git a/src/msbuild/src/Shared/Constants.cs b/src/msbuild/src/Shared/Constants.cs index 3418ad8b214..dcbe23d78bf 100644 --- a/src/msbuild/src/Shared/Constants.cs +++ b/src/msbuild/src/Shared/Constants.cs @@ -154,6 +154,11 @@ internal static class PropertyNames internal const string TargetFrameworks = nameof(TargetFrameworks); internal const string TargetFramework = nameof(TargetFramework); internal const string UsingMicrosoftNETSdk = nameof(UsingMicrosoftNETSdk); + + /// + /// When true, `SkipNonexistentProjects=Build` becomes the default setting of MSBuild tasks. + /// + internal const string BuildNonexistentProjectsByDefault = "_" + nameof(BuildNonexistentProjectsByDefault); } // TODO: Remove these when VS gets updated to setup project cache plugins. diff --git a/src/msbuild/src/Framework/IConstrainedEqualityComparer.cs b/src/msbuild/src/Shared/IConstrainedEqualityComparer.cs similarity index 89% rename from src/msbuild/src/Framework/IConstrainedEqualityComparer.cs rename to src/msbuild/src/Shared/IConstrainedEqualityComparer.cs index 04ad75b4082..c66dc8925f1 100644 --- a/src/msbuild/src/Framework/IConstrainedEqualityComparer.cs +++ b/src/msbuild/src/Shared/IConstrainedEqualityComparer.cs @@ -11,11 +11,7 @@ namespace Microsoft.Build.Collections /// Defines methods to support the comparison of objects for /// equality over constrained inputs. /// -#if TASKHOST - internal interface IConstrainedEqualityComparer : IEqualityComparer -#else internal interface IConstrainedEqualityComparer : IEqualityComparer -#endif { /// /// Determines whether the specified objects are equal, factoring in the specified bounds when comparing . diff --git a/src/msbuild/src/Shared/IsExternalInit.cs b/src/msbuild/src/Shared/IsExternalInit.cs index ae2ffb321cd..f0a0588d1df 100644 --- a/src/msbuild/src/Shared/IsExternalInit.cs +++ b/src/msbuild/src/Shared/IsExternalInit.cs @@ -1,9 +1,22 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#if NET +using System.Runtime.CompilerServices; + +// Type-forward to the inbox class where available, in order to maintain binary compatibility +// between the .NET and .NET Standard 2.0 assemblies. +[assembly: TypeForwardedTo(typeof(IsExternalInit))] + +#else + +using System.ComponentModel; + namespace System.Runtime.CompilerServices { // Needed so we can use init setters in full fw or netstandard // (details: https://developercommunity.visualstudio.com/t/error-cs0518-predefined-type-systemruntimecompiler/1244809) + [EditorBrowsable(EditorBrowsableState.Never)] internal static class IsExternalInit { } } +#endif diff --git a/src/msbuild/src/Framework/MSBuildNameIgnoreCaseComparer.cs b/src/msbuild/src/Shared/MSBuildNameIgnoreCaseComparer.cs similarity index 92% rename from src/msbuild/src/Framework/MSBuildNameIgnoreCaseComparer.cs rename to src/msbuild/src/Shared/MSBuildNameIgnoreCaseComparer.cs index 3a829bec6d2..e8e9a65b9eb 100644 --- a/src/msbuild/src/Framework/MSBuildNameIgnoreCaseComparer.cs +++ b/src/msbuild/src/Shared/MSBuildNameIgnoreCaseComparer.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using Microsoft.Build.Framework; +using Microsoft.Build.Shared; #nullable disable @@ -22,7 +22,7 @@ internal class MSBuildNameIgnoreCaseComparer : IConstrainedEqualityComparer /// The processor architecture on which we are running, but default it will be x86 /// - private static readonly NativeMethods.ProcessorArchitectures s_runningProcessorArchitecture = NativeMethods.ProcessorArchitecture; + private static readonly NativeMethodsShared.ProcessorArchitectures s_runningProcessorArchitecture = NativeMethodsShared.ProcessorArchitecture; /// /// The default immutable comparer instance. @@ -46,12 +46,12 @@ public bool Equals(string compareToString, string constrainedString, int start, { if (lengthToCompare < 0) { - EscapeHatches.ThrowInternalError("Invalid lengthToCompare '{0}' {1} {2}", constrainedString, start, lengthToCompare); + ErrorUtilities.ThrowInternalError("Invalid lengthToCompare '{0}' {1} {2}", constrainedString, start, lengthToCompare); } if (start < 0 || start > (constrainedString?.Length ?? 0) - lengthToCompare) { - EscapeHatches.ThrowInternalError("Invalid start '{0}' {1} {2}", constrainedString, start, lengthToCompare); + ErrorUtilities.ThrowInternalError("Invalid start '{0}' {1} {2}", constrainedString, start, lengthToCompare); } if (ReferenceEquals(compareToString, constrainedString)) @@ -72,8 +72,8 @@ public bool Equals(string compareToString, string constrainedString, int start, return false; } - if ((s_runningProcessorArchitecture != NativeMethods.ProcessorArchitectures.IA64) - && (s_runningProcessorArchitecture != NativeMethods.ProcessorArchitectures.ARM)) + if ((s_runningProcessorArchitecture != NativeMethodsShared.ProcessorArchitectures.IA64) + && (s_runningProcessorArchitecture != NativeMethodsShared.ProcessorArchitectures.ARM)) { // The use of unsafe here is quite a bit faster than the regular // mechanism in the BCL. This is because we can make assumptions @@ -120,8 +120,8 @@ public int GetHashCode(string obj, int start, int length) return 0; // per BCL convention } - if ((s_runningProcessorArchitecture != NativeMethods.ProcessorArchitectures.IA64) - && (s_runningProcessorArchitecture != NativeMethods.ProcessorArchitectures.ARM)) + if ((s_runningProcessorArchitecture != NativeMethodsShared.ProcessorArchitectures.IA64) + && (s_runningProcessorArchitecture != NativeMethodsShared.ProcessorArchitectures.ARM)) { unsafe { diff --git a/src/msbuild/src/Shared/TaskParameter.cs b/src/msbuild/src/Shared/TaskParameter.cs index 12bac552ded..2e397ebab7b 100644 --- a/src/msbuild/src/Shared/TaskParameter.cs +++ b/src/msbuild/src/Shared/TaskParameter.cs @@ -5,10 +5,7 @@ using System.Collections; using System.Collections.Generic; using System.Globalization; -using System.Linq; using System.Reflection; -using Microsoft.Build.Collections; - #if FEATURE_APPDOMAIN using System.Security; #endif @@ -137,7 +134,7 @@ public TaskParameter(object wrappedParameter) { if (inputAsITaskItemArray[i] != null) { - taskItemArrayParameter[i] = new TaskParameterTaskItem(inputAsITaskItemArray[i]); + taskItemArrayParameter[i] = CreateNewTaskItemFrom(inputAsITaskItemArray[i]); } } @@ -176,7 +173,7 @@ public TaskParameter(object wrappedParameter) else if (typeof(ITaskItem).IsAssignableFrom(wrappedParameterType)) { _parameterType = TaskParameterType.ITaskItem; - _wrappedParameter = new TaskParameterTaskItem((ITaskItem)wrappedParameter); + _wrappedParameter = CreateNewTaskItemFrom((ITaskItem)wrappedParameter); } else if (wrappedParameterType.GetTypeInfo().IsValueType) { @@ -279,29 +276,97 @@ public override object InitializeLifetimeService() /// internal static TaskParameter FactoryForDeserialization(ITranslator translator) { - TaskParameter taskParameter = new(); + TaskParameter taskParameter = new TaskParameter(); taskParameter.Translate(translator); return taskParameter; } + /// + /// Creates a new ITaskItem with the contents of the old one. + /// + private ITaskItem CreateNewTaskItemFrom(ITaskItem copyFrom) + { + ITaskItem2 copyFromAsITaskItem2 = copyFrom as ITaskItem2; + string escapedItemSpec; + string escapedDefiningProject; + Dictionary escapedMetadata; + if (copyFromAsITaskItem2 != null) + { + escapedItemSpec = copyFromAsITaskItem2.EvaluatedIncludeEscaped; + escapedDefiningProject = copyFromAsITaskItem2.GetMetadataValueEscaped(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath); + IDictionary nonGenericEscapedMetadata = copyFromAsITaskItem2.CloneCustomMetadataEscaped(); + + escapedMetadata = nonGenericEscapedMetadata as Dictionary; + if (escapedMetadata is null) + { + escapedMetadata = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (object key in nonGenericEscapedMetadata.Keys) + { + escapedMetadata[(string)key] = (string)nonGenericEscapedMetadata[key] ?? String.Empty; + } + } + } + else + { + // If we don't have ITaskItem2 to fall back on, we have to make do with the fact that + // CloneCustomMetadata, GetMetadata, & ItemSpec returns unescaped values, and + // TaskParameterTaskItem's constructor expects escaped values, so escaping them all + // is the closest approximation to correct we can get. + escapedItemSpec = EscapingUtilities.Escape(copyFrom.ItemSpec); + + escapedDefiningProject = EscapingUtilities.EscapeWithCaching(copyFrom.GetMetadata(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath)); + + IDictionary customMetadata = copyFrom.CloneCustomMetadata(); + escapedMetadata = new Dictionary(StringComparer.OrdinalIgnoreCase); + + if (customMetadata?.Count > 0) + { + foreach (string key in customMetadata.Keys) + { + escapedMetadata.Add(key, EscapingUtilities.Escape((string)customMetadata[key] ?? String.Empty)); + } + } + } + + TaskParameterTaskItem taskItem = new TaskParameterTaskItem(escapedItemSpec, escapedDefiningProject, escapedMetadata); + return taskItem; + } + /// /// Serialize / deserialize this item. /// private void TranslateITaskItemArray(ITranslator translator) { - ITaskItem[] wrappedItems = (ITaskItem[])_wrappedParameter; - int length = wrappedItems?.Length ?? 0; - translator.Translate(ref length); - wrappedItems ??= new ITaskItem[length]; + if (!TranslateNullable(translator, _wrappedParameter)) + { + return; + } - for (int i = 0; i < wrappedItems.Length; i++) + if (translator.Mode == TranslationDirection.WriteToStream) { - TaskParameterTaskItem taskItem = (TaskParameterTaskItem)wrappedItems[i]; - translator.Translate(ref taskItem, TaskParameterTaskItem.FactoryForDeserialization); - wrappedItems[i] = taskItem; + ITaskItem[] wrappedItems = (ITaskItem[])_wrappedParameter; + + int length = wrappedItems.Length; + translator.Translate(ref length); + + foreach (ITaskItem wrappedItem in wrappedItems) + { + WriteITaskItem(translator, wrappedItem); + } } + else + { + int length = 0; + translator.Translate(ref length); + ITaskItem[] wrappedItems = new ITaskItem[length]; + + for (int i = 0; i < length; i++) + { + ReadITaskItem(translator, ref wrappedItems[i]); + } - _wrappedParameter = wrappedItems; + _wrappedParameter = wrappedItems; + } } /// @@ -309,9 +374,127 @@ private void TranslateITaskItemArray(ITranslator translator) /// private void TranslateITaskItem(ITranslator translator) { - TaskParameterTaskItem taskItem = (TaskParameterTaskItem)_wrappedParameter; - translator.Translate(ref taskItem, TaskParameterTaskItem.FactoryForDeserialization); - _wrappedParameter = taskItem; + if (translator.Mode == TranslationDirection.WriteToStream) + { + WriteITaskItem(translator, (ITaskItem)_wrappedParameter); + } + else // TranslationDirection.ReadFromStream + { + ITaskItem wrappedItem = null; + ReadITaskItem(translator, ref wrappedItem); + _wrappedParameter = wrappedItem; + } + } + + /// + /// Write the given ITaskItem, using the given write translator + /// + private void WriteITaskItem(ITranslator translator, ITaskItem wrappedItem) + { + ErrorUtilities.VerifyThrow(translator.Mode == TranslationDirection.WriteToStream, "Cannot call this method when reading!"); + + if (!TranslateNullable(translator, wrappedItem)) + { + return; + } + + string escapedItemSpec; + string escapedDefiningProject; + IDictionary wrappedMetadata; + bool wrappedMetadataIsEscaped; + + ITaskItem2 wrappedItemAsITaskItem2 = wrappedItem as ITaskItem2; + + if (wrappedItemAsITaskItem2 != null) + { + escapedItemSpec = wrappedItemAsITaskItem2.EvaluatedIncludeEscaped; + escapedDefiningProject = wrappedItemAsITaskItem2.GetMetadataValueEscaped(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath); + wrappedMetadata = wrappedItemAsITaskItem2.CloneCustomMetadataEscaped(); + wrappedMetadataIsEscaped = true; + } + else + { + // We know that the ITaskItem constructor expects an escaped string, and that ITaskItem.ItemSpec + // is expected to be unescaped, so make sure we give the constructor what it wants. + escapedItemSpec = EscapingUtilities.Escape(wrappedItem.ItemSpec); + escapedDefiningProject = EscapingUtilities.EscapeWithCaching(wrappedItem.GetMetadata(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath)); + wrappedMetadata = wrappedItem.CloneCustomMetadata(); + wrappedMetadataIsEscaped = false; + } + + Dictionary escapedGenericWrappedMetadata = wrappedMetadata as Dictionary; + + if (escapedGenericWrappedMetadata == null) + { + escapedGenericWrappedMetadata = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (object key in wrappedMetadata.Keys) + { + string value = (string)wrappedMetadata[key]; + + if (!wrappedMetadataIsEscaped) + { + value = (value == null) ? value : EscapingUtilities.Escape(value); + } + + escapedGenericWrappedMetadata.Add((string)key, value); + } + } + else if (!wrappedMetadataIsEscaped) + { + foreach (KeyValuePair entry in escapedGenericWrappedMetadata) + { + escapedGenericWrappedMetadata[entry.Key] = entry.Value == null ? entry.Value : EscapingUtilities.Escape(entry.Value); + } + } + + translator.Translate(ref escapedItemSpec); + translator.Translate(ref escapedDefiningProject); + translator.TranslateDictionary(ref escapedGenericWrappedMetadata, StringComparer.OrdinalIgnoreCase); + } + + /// + /// Read an ITaskItem into the given parameter, using the given read translator + /// + private void ReadITaskItem(ITranslator translator, ref ITaskItem wrappedItem) + { + ErrorUtilities.VerifyThrow(translator.Mode == TranslationDirection.ReadFromStream, "Cannot call this method when writing!"); + + if (!TranslateNullable(translator, wrappedItem)) + { + return; + } + + string escapedItemSpec = null; + string escapedDefiningProject = null; + Dictionary escapedMetadata = null; + + translator.Translate(ref escapedItemSpec); + translator.Translate(ref escapedDefiningProject); + translator.TranslateDictionary(ref escapedMetadata, StringComparer.OrdinalIgnoreCase); + + wrappedItem = new TaskParameterTaskItem(escapedItemSpec, escapedDefiningProject, escapedMetadata); + } + + /// + /// Writes out the boolean which says if this object is null or not. + /// + /// The nullable type to translate. + private bool TranslateNullable(ITranslator translator, T value) + { + bool haveRef = false; + + if (translator.Mode == TranslationDirection.WriteToStream) + { + haveRef = (value != null); + translator.Translate(ref haveRef); + } + else // TranslationDirection.ReadFromStream + { + translator.Translate(ref haveRef); + } + + return haveRef; } /// @@ -539,8 +722,7 @@ private class TaskParameterTaskItem : MarshalByRefObject, #endif ITaskItem, - ITaskItem2, - ITranslatable + ITaskItem2 #if !TASKHOST , IMetadataContainer #endif @@ -568,51 +750,13 @@ private class TaskParameterTaskItem : /// /// Constructor for serialization /// - internal TaskParameterTaskItem(ITaskItem copyFrom) + public TaskParameterTaskItem(string escapedItemSpec, string escapedDefiningProject, Dictionary escapedMetadata) { - if (copyFrom is ITaskItem2 copyFromAsITaskItem2) - { - _escapedItemSpec = copyFromAsITaskItem2.EvaluatedIncludeEscaped; - _escapedDefiningProject = copyFromAsITaskItem2.GetMetadataValueEscaped(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath); + ErrorUtilities.VerifyThrowInternalNull(escapedItemSpec); - IDictionary nonGenericEscapedMetadata = copyFromAsITaskItem2.CloneCustomMetadataEscaped(); - _customEscapedMetadata = nonGenericEscapedMetadata as Dictionary; - - if (_customEscapedMetadata is null) - { - _customEscapedMetadata = new Dictionary(MSBuildNameIgnoreCaseComparer.Default); - foreach (DictionaryEntry entry in nonGenericEscapedMetadata) - { - _customEscapedMetadata[(string)entry.Key] = (string)entry.Value ?? string.Empty; - } - } - } - else - { - // If we don't have ITaskItem2 to fall back on, we have to make do with the fact that - // CloneCustomMetadata, GetMetadata, & ItemSpec returns unescaped values, and - // TaskParameterTaskItem's constructor expects escaped values, so escaping them all - // is the closest approximation to correct we can get. - _escapedItemSpec = EscapingUtilities.Escape(copyFrom.ItemSpec); - _escapedDefiningProject = EscapingUtilities.EscapeWithCaching(copyFrom.GetMetadata(FileUtilities.ItemSpecModifiers.DefiningProjectFullPath)); - - IDictionary customMetadata = copyFrom.CloneCustomMetadata(); - _customEscapedMetadata = new Dictionary(MSBuildNameIgnoreCaseComparer.Default); - - if (customMetadata?.Count > 0) - { - foreach (DictionaryEntry entry in customMetadata) - { - _customEscapedMetadata[(string)entry.Key] = EscapingUtilities.Escape((string)entry.Value) ?? string.Empty; - } - } - } - - ErrorUtilities.VerifyThrowInternalNull(_escapedItemSpec); - } - - private TaskParameterTaskItem() - { + _escapedItemSpec = escapedItemSpec; + _escapedDefiningProject = escapedDefiningProject; + _customEscapedMetadata = escapedMetadata; } /// @@ -705,7 +849,7 @@ public void SetMetadata(string metadataName, string metadataValue) // That's why this is IsItemSpecModifier and not IsDerivableItemSpecModifier. ErrorUtilities.VerifyThrowArgument(!FileUtilities.ItemSpecModifiers.IsDerivableItemSpecModifier(metadataName), "Shared.CannotChangeItemSpecModifiers", metadataName); - _customEscapedMetadata ??= new Dictionary(MSBuildNameIgnoreCaseComparer.Default); + _customEscapedMetadata ??= new Dictionary(StringComparer.OrdinalIgnoreCase); _customEscapedMetadata[metadataName] = metadataValue ?? String.Empty; } @@ -745,25 +889,6 @@ public void CopyMetadataTo(ITaskItem destinationItem) // between items, and need to know the source item where the metadata came from string originalItemSpec = destinationItem.GetMetadata("OriginalItemSpec"); -#if !TASKHOST - if (_customEscapedMetadata != null && destinationItem is IMetadataContainer destinationItemAsMetadataContainer) - { - // The destination implements IMetadataContainer so we can use the ImportMetadata bulk-set operation. - IEnumerable> metadataToImport = _customEscapedMetadata - .Where(metadatum => string.IsNullOrEmpty(destinationItem.GetMetadata(metadatum.Key))); - -#if FEATURE_APPDOMAIN - if (!AppDomain.CurrentDomain.IsDefaultAppDomain()) - { - // Linq is not serializable so materialize the collection before making the call. - metadataToImport = metadataToImport.ToList(); - } -#endif - - destinationItemAsMetadataContainer.ImportMetadata(metadataToImport); - } - else -#endif if (_customEscapedMetadata != null) { foreach (KeyValuePair entry in _customEscapedMetadata) @@ -794,7 +919,7 @@ public void CopyMetadataTo(ITaskItem destinationItem) /// Dictionary of cloned metadata public IDictionary CloneCustomMetadata() { - IDictionary clonedMetadata = new Dictionary(MSBuildNameIgnoreCaseComparer.Default); + IDictionary clonedMetadata = new Dictionary(StringComparer.OrdinalIgnoreCase); if (_customEscapedMetadata != null) { @@ -913,23 +1038,6 @@ public void ImportMetadata(IEnumerable> metadata) SetMetadata(kvp.Key, kvp.Value); } } - - public void Translate(ITranslator translator) - { - translator.Translate(ref _escapedItemSpec); - translator.Translate(ref _escapedDefiningProject); - translator.TranslateDictionary(ref _customEscapedMetadata, MSBuildNameIgnoreCaseComparer.Default); - - ErrorUtilities.VerifyThrowInternalNull(_escapedItemSpec); - ErrorUtilities.VerifyThrowInternalNull(_customEscapedMetadata); - } - - internal static TaskParameterTaskItem FactoryForDeserialization(ITranslator translator) - { - TaskParameterTaskItem taskItem = new(); - taskItem.Translate(translator); - return taskItem; - } } } } diff --git a/src/msbuild/src/Tasks/MSBuild.cs b/src/msbuild/src/Tasks/MSBuild.cs index 12426e0c9aa..d3c24bd0f1d 100644 --- a/src/msbuild/src/Tasks/MSBuild.cs +++ b/src/msbuild/src/Tasks/MSBuild.cs @@ -296,6 +296,12 @@ public override bool Execute() { skipNonExistProjects = behavior; } + else if (BuildEngine is IBuildEngine6 buildEngine6 && buildEngine6.GetGlobalProperties() + .TryGetValue(PropertyNames.BuildNonexistentProjectsByDefault, out var buildNonexistentProjectsByDefault) && + ConversionUtilities.ConvertStringToBool(buildNonexistentProjectsByDefault)) + { + skipNonExistProjects = SkipNonExistentProjectsBehavior.Build; + } else { skipNonExistProjects = SkipNonExistentProjectsBehavior.Error; diff --git a/src/msbuild/src/Tasks/Microsoft.Build.Tasks.csproj b/src/msbuild/src/Tasks/Microsoft.Build.Tasks.csproj index 4fa44bebcbf..48d3df90c79 100644 --- a/src/msbuild/src/Tasks/Microsoft.Build.Tasks.csproj +++ b/src/msbuild/src/Tasks/Microsoft.Build.Tasks.csproj @@ -87,6 +87,7 @@ FileDelegates.cs + PropertyParser.cs @@ -131,6 +132,7 @@ Modifiers.cs + diff --git a/src/msbuild/src/Tasks/Microsoft.Common.CurrentVersion.targets b/src/msbuild/src/Tasks/Microsoft.Common.CurrentVersion.targets index 0513ae5bcb8..25552982719 100644 --- a/src/msbuild/src/Tasks/Microsoft.Common.CurrentVersion.targets +++ b/src/msbuild/src/Tasks/Microsoft.Common.CurrentVersion.targets @@ -3189,8 +3189,7 @@ Copyright (C) Microsoft Corporation. All rights reserved. AssignTargetPaths; SplitResourcesByCulture; CreateManifestResourceNames; - CreateCustomManifestResourceNames; - AssignEmbeddedResourceOutputPaths; + CreateCustomManifestResourceNames @@ -3248,17 +3247,6 @@ Copyright (C) Microsoft Corporation. All rights reserved. - - - - - $(IntermediateOutputPath)%(EmbeddedResource.ManifestResourceName).resources - - - - - + Shared\FrameworkLocationHelper.cs + + Shared\IConstrainedEqualityComparer.cs + Shared\IKeyed.cs + + Shared\MSBuildNameIgnoreCaseComparer.cs + Shared\Modifiers.cs diff --git a/src/roslyn/eng/Directory.Packages.props b/src/roslyn/eng/Directory.Packages.props index 917a8e7b547..aa611b4cbb4 100644 --- a/src/roslyn/eng/Directory.Packages.props +++ b/src/roslyn/eng/Directory.Packages.props @@ -273,7 +273,7 @@ - + diff --git a/src/roslyn/eng/Versions.props b/src/roslyn/eng/Versions.props index 316b98b4558..a70c9228798 100644 --- a/src/roslyn/eng/Versions.props +++ b/src/roslyn/eng/Versions.props @@ -8,7 +8,7 @@ 5 0 0 - 1 + 2 $(MajorVersion).$(MinorVersion).$(PatchVersion) - 17.5.0 + 17.13.0 diff --git a/src/roslyn/eng/config/PublishData.json b/src/roslyn/eng/config/PublishData.json index 9727fa29ce6..4ad30f47e37 100644 --- a/src/roslyn/eng/config/PublishData.json +++ b/src/roslyn/eng/config/PublishData.json @@ -176,6 +176,15 @@ "insertionTitlePrefix": "[d17.14]", "insertionCreateDraftPR": false }, + "release/dev-next": { + "nugetKind": [ + "Shipping", + "NonShipping" + ], + "vsBranch": "main", + "insertionTitlePrefix": "[dNext]", + "insertionCreateDraftPR": false + }, "main": { "nugetKind": [ "Shipping", @@ -191,8 +200,8 @@ "NonShipping" ], "vsBranch": "main", - "insertionCreateDraftPR": false, - "insertionTitlePrefix": "[d17.15 P1]" + "insertionCreateDraftPR": true, + "insertionTitlePrefix": "[dNext.1]" } } } diff --git a/src/roslyn/src/Analyzers/CSharp/CodeFixes/ImplementInterface/CSharpImplementInterfaceCodeFixProvider.cs b/src/roslyn/src/Analyzers/CSharp/CodeFixes/ImplementInterface/CSharpImplementInterfaceCodeFixProvider.cs index 0e57a94e02e..a755f4763ee 100644 --- a/src/roslyn/src/Analyzers/CSharp/CodeFixes/ImplementInterface/CSharpImplementInterfaceCodeFixProvider.cs +++ b/src/roslyn/src/Analyzers/CSharp/CodeFixes/ImplementInterface/CSharpImplementInterfaceCodeFixProvider.cs @@ -24,7 +24,4 @@ internal sealed class CSharpImplementInterfaceCodeFixProvider() public sealed override ImmutableArray FixableDiagnosticIds { get; } = [CS0535, CS0737, CS0738]; - - protected override bool IsTypeInInterfaceBaseList(TypeSyntax type) - => type.Parent is BaseTypeSyntax { Parent: BaseListSyntax } baseTypeParent && baseTypeParent.Type == type; } diff --git a/src/roslyn/src/Analyzers/CSharp/CodeFixes/ImplementInterface/CSharpImplementInterfaceService.cs b/src/roslyn/src/Analyzers/CSharp/CodeFixes/ImplementInterface/CSharpImplementInterfaceService.cs index 23efc1a7f4f..b9fd6197a06 100644 --- a/src/roslyn/src/Analyzers/CSharp/CodeFixes/ImplementInterface/CSharpImplementInterfaceService.cs +++ b/src/roslyn/src/Analyzers/CSharp/CodeFixes/ImplementInterface/CSharpImplementInterfaceService.cs @@ -16,6 +16,7 @@ using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.ImplementInterface; +using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.CSharp.ImplementInterface; @@ -23,7 +24,7 @@ namespace Microsoft.CodeAnalysis.CSharp.ImplementInterface; [ExportLanguageService(typeof(IImplementInterfaceService), LanguageNames.CSharp), Shared] [method: ImportingConstructor] [method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class CSharpImplementInterfaceService() : AbstractImplementInterfaceService +internal sealed class CSharpImplementInterfaceService() : AbstractImplementInterfaceService { protected override ISyntaxFormatting SyntaxFormatting => CSharpSyntaxFormatting.Instance; @@ -37,6 +38,18 @@ protected override string ToDisplayString(IMethodSymbol disposeImplMethod, Symbo protected override bool AllowDelegateAndEnumConstraints(ParseOptions options) => options.LanguageVersion() >= LanguageVersion.CSharp7_3; + protected override bool IsTypeInInterfaceBaseList(SyntaxNode? type) + => type?.Parent is BaseTypeSyntax { Parent: BaseListSyntax } baseTypeParent && baseTypeParent.Type == type; + + protected override void AddInterfaceTypes(TypeDeclarationSyntax typeDeclaration, ArrayBuilder result) + { + if (typeDeclaration.BaseList != null) + { + foreach (var baseType in typeDeclaration.BaseList.Types) + result.Add(baseType.Type); + } + } + protected override bool TryInitializeState( Document document, SemanticModel model, SyntaxNode node, CancellationToken cancellationToken, [NotNullWhen(true)] out SyntaxNode? classOrStructDecl, diff --git a/src/roslyn/src/Analyzers/CSharp/Tests/CSharpAnalyzers.UnitTests.projitems b/src/roslyn/src/Analyzers/CSharp/Tests/CSharpAnalyzers.UnitTests.projitems index 2fb30453912..26423cafb96 100644 --- a/src/roslyn/src/Analyzers/CSharp/Tests/CSharpAnalyzers.UnitTests.projitems +++ b/src/roslyn/src/Analyzers/CSharp/Tests/CSharpAnalyzers.UnitTests.projitems @@ -43,8 +43,8 @@ - - + + diff --git a/src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceTests.cs b/src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceCodeFixTests.cs similarity index 99% rename from src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceTests.cs rename to src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceCodeFixTests.cs index ec10365e15a..e7e6d5dbf14 100644 --- a/src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceTests.cs +++ b/src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceCodeFixTests.cs @@ -23,7 +23,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ImplementInterface; CSharpImplementInterfaceCodeFixProvider>; [Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)] -public sealed class ImplementInterfaceTests +public sealed class ImplementInterfaceCodeFixTests { private readonly NamingStylesTestOptionSets _options = new(LanguageNames.CSharp); diff --git a/src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceTests_FixAllTests.cs b/src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceCodeFixTests_FixAllTests.cs similarity index 99% rename from src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceTests_FixAllTests.cs rename to src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceCodeFixTests_FixAllTests.cs index 761d785b2ea..afc9042b849 100644 --- a/src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceTests_FixAllTests.cs +++ b/src/roslyn/src/Analyzers/CSharp/Tests/ImplementInterface/ImplementInterfaceCodeFixTests_FixAllTests.cs @@ -15,7 +15,7 @@ namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.ImplementInterface; EmptyDiagnosticAnalyzer, CSharpImplementInterfaceCodeFixProvider>; -public sealed class ImplementInterfaceTests_FixAllTests +public sealed class ImplementInterfaceCodeFixTests_FixAllTests { #region "Fix all occurrences tests" diff --git a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceCodeFixProvider.cs b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceCodeFixProvider.cs index da11cdb7fca..7fffec0d40d 100644 --- a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceCodeFixProvider.cs +++ b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceCodeFixProvider.cs @@ -2,28 +2,16 @@ // 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.Collections.Immutable; using System.Linq; -using System.Runtime.CompilerServices; -using System.Threading; using System.Threading.Tasks; -using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.ImplementType; -using Microsoft.CodeAnalysis.LanguageService; -using Microsoft.CodeAnalysis.PooledObjects; using Microsoft.CodeAnalysis.Shared.Extensions; namespace Microsoft.CodeAnalysis.ImplementInterface; -using static ImplementHelpers; - internal abstract class AbstractImplementInterfaceCodeFixProvider : CodeFixProvider where TTypeSyntax : SyntaxNode { - protected abstract bool IsTypeInInterfaceBaseList(TTypeSyntax type); - public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; @@ -39,173 +27,11 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) if (!token.Span.IntersectsWith(span)) return; - var options = await document.GetImplementTypeOptionsAsync(cancellationToken).ConfigureAwait(false); - - foreach (var type in token.Parent.GetAncestorsOrThis()) - { - if (this.IsTypeInInterfaceBaseList(type)) - { - var service = document.GetRequiredLanguageService(); - - var info = await service.AnalyzeAsync( - document, type, cancellationToken).ConfigureAwait(false); - if (info is not null) - { - using var _ = ArrayBuilder.GetInstance(out var codeActions); - await foreach (var implementOptions in GetImplementOptionsAsync(document, info, cancellationToken)) - { - var title = GetTitle(implementOptions); - var equivalenceKey = GetEquivalenceKey(info, implementOptions); - codeActions.Add(CodeAction.Create( - title, - cancellationToken => service.ImplementInterfaceAsync( - document, info, options, implementOptions, cancellationToken), - equivalenceKey)); - } - - context.RegisterFixes(codeActions, context.Diagnostics); - } - - break; - } - } - } - - private static string GetTitle(ImplementInterfaceConfiguration options) - { - if (options.ImplementDisposePattern) - { - return options.Explicitly - ? CodeFixesResources.Implement_interface_explicitly_with_Dispose_pattern - : CodeFixesResources.Implement_interface_with_Dispose_pattern; - } - else if (options.Explicitly) - { - return options.OnlyRemaining - ? CodeFixesResources.Implement_remaining_members_explicitly - : CodeFixesResources.Implement_all_members_explicitly; - } - else if (options.Abstractly) - { - return CodeFixesResources.Implement_interface_abstractly; - } - else if (options.ThroughMember != null) - { - return string.Format(CodeFixesResources.Implement_interface_through_0, options.ThroughMember.Name); - } - else - { - return CodeFixesResources.Implement_interface; - } - } - - private static string GetEquivalenceKey( - ImplementInterfaceInfo state, - ImplementInterfaceConfiguration options) - { - var interfaceType = state.InterfaceTypes.First(); - var typeName = interfaceType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); - - // Legacy part of the equivalence key. Kept the same to avoid test churn. - var codeActionTypeName = options.ImplementDisposePattern - ? "Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService+ImplementInterfaceWithDisposePatternCodeAction" - : "Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService+ImplementInterfaceCodeAction"; - - // Consider code actions equivalent if they correspond to the same interface being implemented elsewhere - // in the same manner. Note: 'implement through member' means implementing the same interface through - // an applicable member with the same name in the destination. - return options.Explicitly.ToString() + ";" + - options.Abstractly.ToString() + ";" + - options.OnlyRemaining.ToString() + ":" + - typeName + ";" + - codeActionTypeName + ";" + - options.ThroughMember?.Name; - } - - private static async IAsyncEnumerable GetImplementOptionsAsync( - Document document, ImplementInterfaceInfo state, [EnumeratorCancellation] CancellationToken cancellationToken) - { - var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); - var syntaxFacts = document.GetRequiredLanguageService(); - var supportsImplicitImplementationOfNonPublicInterfaceMembers = syntaxFacts.SupportsImplicitImplementationOfNonPublicInterfaceMembers(document.Project.ParseOptions!); - if (state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented.Length > 0) - { - var totalMemberCount = 0; - var inaccessibleMemberCount = 0; - - foreach (var (_, members) in state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented) - { - foreach (var member in members) - { - totalMemberCount++; - - if (ContainsTypeLessAccessibleThan(member, state.ClassOrStructType, supportsImplicitImplementationOfNonPublicInterfaceMembers)) - inaccessibleMemberCount++; - } - } - - // If all members to implement are inaccessible, then "Implement interface" codeaction - // will be the same as "Implement interface explicitly", so there is no point in having both of them - if (totalMemberCount != inaccessibleMemberCount) - yield return new() { OnlyRemaining = true }; - - if (ShouldImplementDisposePattern(compilation, state, explicitly: false)) - yield return new() { OnlyRemaining = true, ImplementDisposePattern = true, }; - - var delegatableMembers = GetDelegatableMembers(document, state, cancellationToken); - foreach (var member in delegatableMembers) - yield return new() { ThroughMember = member }; + var type = token.Parent.GetAncestorsOrThis().LastOrDefault(); - if (state.ClassOrStructType.IsAbstract) - yield return new() { OnlyRemaining = true, Abstractly = true }; - } - - if (state.MembersWithoutExplicitImplementation.Length > 0) - { - yield return new() { Explicitly = true }; - - if (ShouldImplementDisposePattern(compilation, state, explicitly: true)) - yield return new() { ImplementDisposePattern = true, Explicitly = true }; - } - - if (AnyImplementedImplicitly(state)) - yield return new() { OnlyRemaining = true, Explicitly = true }; - } - - private static bool AnyImplementedImplicitly(ImplementInterfaceInfo state) - { - if (state.MembersWithoutExplicitOrImplicitImplementation.Length != state.MembersWithoutExplicitImplementation.Length) - { - return true; - } - - for (var i = 0; i < state.MembersWithoutExplicitOrImplicitImplementation.Length; i++) - { - var (typeA, membersA) = state.MembersWithoutExplicitOrImplicitImplementation[i]; - var (typeB, membersB) = state.MembersWithoutExplicitImplementation[i]; - if (!typeA.Equals(typeB)) - { - return true; - } - - if (!membersA.SequenceEqual(membersB)) - { - return true; - } - } - - return false; - } - - private static ImmutableArray GetDelegatableMembers( - Document document, ImplementInterfaceInfo state, CancellationToken cancellationToken) - { - var firstInterfaceType = state.InterfaceTypes.First(); + var service = document.GetRequiredLanguageService(); + var codeActions = await service.GetCodeActionsAsync(document, type, cancellationToken).ConfigureAwait(false); - return ImplementHelpers.GetDelegatableMembers( - document, - state.ClassOrStructType, - t => t.GetAllInterfacesIncludingThis().Contains(firstInterfaceType), - cancellationToken); + context.RegisterFixes(codeActions, context.Diagnostics); } } diff --git a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.State.cs b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.State.cs index 282036cd5b4..cff4072d33c 100644 --- a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.State.cs +++ b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.State.cs @@ -9,7 +9,7 @@ namespace Microsoft.CodeAnalysis.ImplementInterface; -internal abstract partial class AbstractImplementInterfaceService +internal abstract partial class AbstractImplementInterfaceService { internal sealed class State( Document document, @@ -40,7 +40,7 @@ internal sealed class State( public ImmutableArray<(INamedTypeSymbol type, ImmutableArray members)> MembersWithoutExplicitImplementation => Info.MembersWithoutExplicitImplementation; public static State? Generate( - AbstractImplementInterfaceService service, + AbstractImplementInterfaceService service, Document document, SemanticModel model, SyntaxNode interfaceNode, diff --git a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.cs b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.cs index 9ccbb6fe9ce..0d85020a1be 100644 --- a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.cs +++ b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.cs @@ -3,10 +3,14 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.ImplementType; @@ -19,7 +23,8 @@ namespace Microsoft.CodeAnalysis.ImplementInterface; using static ImplementHelpers; -internal abstract partial class AbstractImplementInterfaceService() : IImplementInterfaceService +internal abstract partial class AbstractImplementInterfaceService : IImplementInterfaceService + where TTypeDeclarationSyntax : SyntaxNode { protected const string DisposingName = "disposing"; @@ -39,6 +44,18 @@ protected abstract bool TryInitializeState(Document document, SemanticModel mode protected abstract SyntaxNode AddCommentInsideIfStatement(SyntaxNode ifDisposingStatement, SyntaxTriviaList trivia); protected abstract SyntaxNode CreateFinalizer(SyntaxGenerator generator, INamedTypeSymbol classType, string disposeMethodDisplayString); + protected abstract bool IsTypeInInterfaceBaseList([NotNullWhen(true)] SyntaxNode? type); + protected abstract void AddInterfaceTypes(TTypeDeclarationSyntax typeDeclaration, ArrayBuilder result); + + public ImmutableArray GetInterfaceTypes(SyntaxNode typeDeclaration) + { + using var _ = ArrayBuilder.GetInstance(out var result); + if (typeDeclaration is TTypeDeclarationSyntax typeSyntax) + AddInterfaceTypes(typeSyntax, result); + + return result.ToImmutableAndClear(); + } + public async Task ImplementInterfaceAsync( Document document, ImplementTypeOptions options, SyntaxNode node, CancellationToken cancellationToken) { @@ -59,7 +76,7 @@ public async Task ImplementInterfaceAsync( } } - public async Task AnalyzeAsync(Document document, SyntaxNode interfaceType, CancellationToken cancellationToken) + private async Task AnalyzeAsync(Document document, SyntaxNode interfaceType, CancellationToken cancellationToken) { var model = await document.GetRequiredSemanticModelAsync(cancellationToken).ConfigureAwait(false); return State.Generate(this, document, model, interfaceType, cancellationToken)?.Info; @@ -88,7 +105,7 @@ protected SyntaxTriviaList CreateCommentTrivia( return [.. trivia]; } - public async Task ImplementInterfaceAsync( + private async Task ImplementInterfaceAsync( Document document, ImplementInterfaceInfo info, ImplementTypeOptions options, @@ -126,4 +143,169 @@ public ImmutableArray ImplementInterfaceMember( return implementedMembers; } + + public async Task> GetCodeActionsAsync(Document document, SyntaxNode? interfaceType, CancellationToken cancellationToken) + { + var options = await document.GetImplementTypeOptionsAsync(cancellationToken).ConfigureAwait(false); + + if (!this.IsTypeInInterfaceBaseList(interfaceType)) + return []; + + var info = await this.AnalyzeAsync( + document, interfaceType, cancellationToken).ConfigureAwait(false); + if (info is null) + return []; + + using var _ = ArrayBuilder.GetInstance(out var codeActions); + await foreach (var implementOptions in GetImplementOptionsAsync(document, info, cancellationToken)) + { + var title = GetTitle(implementOptions); + var equivalenceKey = GetEquivalenceKey(info, implementOptions); + codeActions.Add(CodeAction.Create( + title, + cancellationToken => this.ImplementInterfaceAsync( + document, info, options, implementOptions, cancellationToken), + equivalenceKey)); + } + + return codeActions.ToImmutableAndClear(); + } + + private static async IAsyncEnumerable GetImplementOptionsAsync( + Document document, ImplementInterfaceInfo state, [EnumeratorCancellation] CancellationToken cancellationToken) + { + var compilation = await document.Project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); + var syntaxFacts = document.GetRequiredLanguageService(); + var supportsImplicitImplementationOfNonPublicInterfaceMembers = syntaxFacts.SupportsImplicitImplementationOfNonPublicInterfaceMembers(document.Project.ParseOptions!); + if (state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented.Length > 0) + { + var totalMemberCount = 0; + var inaccessibleMemberCount = 0; + + foreach (var (_, members) in state.MembersWithoutExplicitOrImplicitImplementationWhichCanBeImplicitlyImplemented) + { + foreach (var member in members) + { + totalMemberCount++; + + if (ContainsTypeLessAccessibleThan(member, state.ClassOrStructType, supportsImplicitImplementationOfNonPublicInterfaceMembers)) + inaccessibleMemberCount++; + } + } + + // If all members to implement are inaccessible, then "Implement interface" codeaction + // will be the same as "Implement interface explicitly", so there is no point in having both of them + if (totalMemberCount != inaccessibleMemberCount) + yield return new() { OnlyRemaining = true }; + + if (ShouldImplementDisposePattern(compilation, state, explicitly: false)) + yield return new() { OnlyRemaining = true, ImplementDisposePattern = true, }; + + var delegatableMembers = GetDelegatableMembers(document, state, cancellationToken); + foreach (var member in delegatableMembers) + yield return new() { ThroughMember = member }; + + if (state.ClassOrStructType.IsAbstract) + yield return new() { OnlyRemaining = true, Abstractly = true }; + } + + if (state.MembersWithoutExplicitImplementation.Length > 0) + { + yield return new() { Explicitly = true }; + + if (ShouldImplementDisposePattern(compilation, state, explicitly: true)) + yield return new() { ImplementDisposePattern = true, Explicitly = true }; + } + + if (AnyImplementedImplicitly(state)) + yield return new() { OnlyRemaining = true, Explicitly = true }; + } + + private static string GetTitle(ImplementInterfaceConfiguration options) + { + if (options.ImplementDisposePattern) + { + return options.Explicitly + ? CodeFixesResources.Implement_interface_explicitly_with_Dispose_pattern + : CodeFixesResources.Implement_interface_with_Dispose_pattern; + } + else if (options.Explicitly) + { + return options.OnlyRemaining + ? CodeFixesResources.Implement_remaining_members_explicitly + : CodeFixesResources.Implement_all_members_explicitly; + } + else if (options.Abstractly) + { + return CodeFixesResources.Implement_interface_abstractly; + } + else if (options.ThroughMember != null) + { + return string.Format(CodeFixesResources.Implement_interface_through_0, options.ThroughMember.Name); + } + else + { + return CodeFixesResources.Implement_interface; + } + } + + private static string GetEquivalenceKey( + ImplementInterfaceInfo state, + ImplementInterfaceConfiguration options) + { + var interfaceType = state.InterfaceTypes.First(); + var typeName = interfaceType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + + // Legacy part of the equivalence key. Kept the same to avoid test churn. + var codeActionTypeName = options.ImplementDisposePattern + ? "Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService+ImplementInterfaceWithDisposePatternCodeAction" + : "Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService+ImplementInterfaceCodeAction"; + + // Consider code actions equivalent if they correspond to the same interface being implemented elsewhere + // in the same manner. Note: 'implement through member' means implementing the same interface through + // an applicable member with the same name in the destination. + return options.Explicitly.ToString() + ";" + + options.Abstractly.ToString() + ";" + + options.OnlyRemaining.ToString() + ":" + + typeName + ";" + + codeActionTypeName + ";" + + options.ThroughMember?.Name; + } + + private static bool AnyImplementedImplicitly(ImplementInterfaceInfo state) + { + if (state.MembersWithoutExplicitOrImplicitImplementation.Length != state.MembersWithoutExplicitImplementation.Length) + { + return true; + } + + for (var i = 0; i < state.MembersWithoutExplicitOrImplicitImplementation.Length; i++) + { + var (typeA, membersA) = state.MembersWithoutExplicitOrImplicitImplementation[i]; + var (typeB, membersB) = state.MembersWithoutExplicitImplementation[i]; + if (!typeA.Equals(typeB)) + { + return true; + } + + if (!membersA.SequenceEqual(membersB)) + { + return true; + } + } + + return false; + } + + private static ImmutableArray GetDelegatableMembers( + Document document, ImplementInterfaceInfo state, CancellationToken cancellationToken) + { + var firstInterfaceType = state.InterfaceTypes.First(); + + return ImplementHelpers.GetDelegatableMembers( + document, + state.ClassOrStructType, + t => t.GetAllInterfacesIncludingThis().Contains(firstInterfaceType), + cancellationToken); + } } diff --git a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/IImplementInterfaceService.cs b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/IImplementInterfaceService.cs index 55b0b6d99cd..32df9beb853 100644 --- a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/IImplementInterfaceService.cs +++ b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/IImplementInterfaceService.cs @@ -5,6 +5,7 @@ using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.ImplementType; @@ -23,15 +24,6 @@ internal interface IImplementInterfaceService : ILanguageService { Task ImplementInterfaceAsync(Document document, ImplementTypeOptions options, SyntaxNode node, CancellationToken cancellationToken); - Task AnalyzeAsync(Document document, SyntaxNode interfaceType, CancellationToken cancellationToken); - - Task ImplementInterfaceAsync( - Document document, - ImplementInterfaceInfo info, - ImplementTypeOptions options, - ImplementInterfaceConfiguration configuration, - CancellationToken cancellationToken); - /// /// Produces the symbol that implements that provided within the corresponding /// , based on the provided and @@ -44,4 +36,9 @@ ImmutableArray ImplementInterfaceMember( ImplementInterfaceConfiguration configuration, Compilation compilation, ISymbol interfaceMember); + + Task> GetCodeActionsAsync( + Document document, SyntaxNode? interfaceType, CancellationToken cancellationToken); + + ImmutableArray GetInterfaceTypes(SyntaxNode typeDeclaration); } diff --git a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator.cs b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator.cs index fc5078f1ea9..b0b61f3fdbc 100644 --- a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator.cs +++ b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator.cs @@ -22,12 +22,12 @@ namespace Microsoft.CodeAnalysis.ImplementInterface; using static ImplementHelpers; -internal abstract partial class AbstractImplementInterfaceService +internal abstract partial class AbstractImplementInterfaceService { private sealed partial class ImplementInterfaceGenerator { private readonly Document Document; - private readonly AbstractImplementInterfaceService Service; + private readonly AbstractImplementInterfaceService Service; private readonly ImplementInterfaceInfo State; private readonly ImplementTypeOptions Options; @@ -40,7 +40,7 @@ private sealed partial class ImplementInterfaceGenerator private ISymbol? ThroughMember => Configuration.ThroughMember; internal ImplementInterfaceGenerator( - AbstractImplementInterfaceService service, + AbstractImplementInterfaceService service, Document document, ImplementInterfaceInfo state, ImplementTypeOptions options, diff --git a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Conflicts.cs b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Conflicts.cs index fb554b99f44..f9ce33830bc 100644 --- a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Conflicts.cs +++ b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Conflicts.cs @@ -12,7 +12,7 @@ namespace Microsoft.CodeAnalysis.ImplementInterface; -internal abstract partial class AbstractImplementInterfaceService +internal abstract partial class AbstractImplementInterfaceService { private sealed partial class ImplementInterfaceGenerator { diff --git a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_DisposePattern.cs b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_DisposePattern.cs index 0887f5f52ce..4bc54edb2fc 100644 --- a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_DisposePattern.cs +++ b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_DisposePattern.cs @@ -22,7 +22,7 @@ namespace Microsoft.CodeAnalysis.ImplementInterface; using static ImplementHelpers; -internal abstract partial class AbstractImplementInterfaceService +internal abstract partial class AbstractImplementInterfaceService { private sealed partial class ImplementInterfaceGenerator { diff --git a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Method.cs b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Method.cs index 48a343cdcfe..a08aa2daff3 100644 --- a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Method.cs +++ b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Method.cs @@ -11,7 +11,7 @@ namespace Microsoft.CodeAnalysis.ImplementInterface; -internal abstract partial class AbstractImplementInterfaceService +internal abstract partial class AbstractImplementInterfaceService { private sealed partial class ImplementInterfaceGenerator { diff --git a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Property.cs b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Property.cs index b31a55c26bb..75b8cd535f3 100644 --- a/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Property.cs +++ b/src/roslyn/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Property.cs @@ -16,7 +16,7 @@ namespace Microsoft.CodeAnalysis.ImplementInterface; -internal abstract partial class AbstractImplementInterfaceService +internal abstract partial class AbstractImplementInterfaceService { private sealed partial class ImplementInterfaceGenerator { diff --git a/src/roslyn/src/Analyzers/VisualBasic/CodeFixes/ImplementInterface/VisualBasicImplementInterfaceCodeFixProvider.vb b/src/roslyn/src/Analyzers/VisualBasic/CodeFixes/ImplementInterface/VisualBasicImplementInterfaceCodeFixProvider.vb index 8aa097942b9..634e140216f 100644 --- a/src/roslyn/src/Analyzers/VisualBasic/CodeFixes/ImplementInterface/VisualBasicImplementInterfaceCodeFixProvider.vb +++ b/src/roslyn/src/Analyzers/VisualBasic/CodeFixes/ImplementInterface/VisualBasicImplementInterfaceCodeFixProvider.vb @@ -23,9 +23,5 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ImplementInterface End Sub Public Overrides ReadOnly Property FixableDiagnosticIds As ImmutableArray(Of String) = ImmutableArray.Create(BC30149) - - Protected Overrides Function IsTypeInInterfaceBaseList(type As TypeSyntax) As Boolean - Return TypeOf type.Parent Is ImplementsStatementSyntax - End Function End Class End Namespace diff --git a/src/roslyn/src/Analyzers/VisualBasic/CodeFixes/ImplementInterface/VisualBasicImplementInterfaceService.vb b/src/roslyn/src/Analyzers/VisualBasic/CodeFixes/ImplementInterface/VisualBasicImplementInterfaceService.vb index 161a9857bd4..eb0d4a2a879 100644 --- a/src/roslyn/src/Analyzers/VisualBasic/CodeFixes/ImplementInterface/VisualBasicImplementInterfaceService.vb +++ b/src/roslyn/src/Analyzers/VisualBasic/CodeFixes/ImplementInterface/VisualBasicImplementInterfaceService.vb @@ -10,14 +10,15 @@ Imports Microsoft.CodeAnalysis.Editing Imports Microsoft.CodeAnalysis.Formatting Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.ImplementInterface +Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.VisualBasic.CodeGeneration Imports Microsoft.CodeAnalysis.VisualBasic.Formatting Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.ImplementInterface - Partial Friend Class VisualBasicImplementInterfaceService - Inherits AbstractImplementInterfaceService + Partial Friend NotInheritable Class VisualBasicImplementInterfaceService + Inherits AbstractImplementInterfaceService(Of TypeBlockSyntax) @@ -39,6 +40,18 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.ImplementInterface Return False End Function + Protected Overrides Function IsTypeInInterfaceBaseList(type As SyntaxNode) As Boolean + Return TypeOf type?.Parent Is ImplementsStatementSyntax + End Function + + Protected Overrides Sub AddInterfaceTypes(typeDeclaration As TypeBlockSyntax, result As ArrayBuilder(Of SyntaxNode)) + For Each implementsStatement In typeDeclaration.Implements + For Each interfaceType In implementsStatement.Types + result.Add(interfaceType) + Next + Next + End Sub + Protected Overrides Function TryInitializeState( document As Document, model As SemanticModel, node As SyntaxNode, cancellationToken As CancellationToken, ByRef classOrStructDecl As SyntaxNode, ByRef classOrStructType As INamedTypeSymbol, diff --git a/src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceTests.vb b/src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceCodeFixTests.vb similarity index 99% rename from src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceTests.vb rename to src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceCodeFixTests.vb index 9b9f0deaa81..583aba10158 100644 --- a/src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceTests.vb +++ b/src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceCodeFixTests.vb @@ -10,7 +10,7 @@ Imports Microsoft.CodeAnalysis.VisualBasic.ImplementInterface Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ImplementInterface - Partial Public Class ImplementInterfaceTests + Partial Public Class ImplementInterfaceCodeFixTests Inherits AbstractVisualBasicDiagnosticProviderBasedUserDiagnosticTest_NoEditor Friend Overrides Function CreateDiagnosticProviderAndFixer(workspace As Workspace) As (DiagnosticAnalyzer, CodeFixProvider) diff --git a/src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceTests_FixAllTests.vb b/src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceCodeFixTests_FixAllTests.vb similarity index 99% rename from src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceTests_FixAllTests.vb rename to src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceCodeFixTests_FixAllTests.vb index 46138758ecf..4f5fd12b08d 100644 --- a/src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceTests_FixAllTests.vb +++ b/src/roslyn/src/Analyzers/VisualBasic/Tests/ImplementInterface/ImplementInterfaceCodeFixTests_FixAllTests.vb @@ -3,7 +3,7 @@ ' See the LICENSE file in the project root for more information. Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.ImplementInterface - Partial Public Class ImplementInterfaceTests + Partial Public Class ImplementInterfaceCodeFixTests diff --git a/src/roslyn/src/Analyzers/VisualBasic/Tests/VisualBasicAnalyzers.UnitTests.projitems b/src/roslyn/src/Analyzers/VisualBasic/Tests/VisualBasicAnalyzers.UnitTests.projitems index 9f5434bfc46..fcfafc799ce 100644 --- a/src/roslyn/src/Analyzers/VisualBasic/Tests/VisualBasicAnalyzers.UnitTests.projitems +++ b/src/roslyn/src/Analyzers/VisualBasic/Tests/VisualBasicAnalyzers.UnitTests.projitems @@ -29,8 +29,8 @@ - - + + diff --git a/src/roslyn/src/Compilers/CSharp/Portable/CSharpParseOptions.cs b/src/roslyn/src/Compilers/CSharp/Portable/CSharpParseOptions.cs index 650f5b27cf0..bc3804f6725 100644 --- a/src/roslyn/src/Compilers/CSharp/Portable/CSharpParseOptions.cs +++ b/src/roslyn/src/Compilers/CSharp/Portable/CSharpParseOptions.cs @@ -162,9 +162,15 @@ protected override ParseOptions CommonWithFeatures(IEnumerable public new CSharpParseOptions WithFeatures(IEnumerable>? features) { - ImmutableDictionary dictionary = - features?.ToImmutableDictionary(StringComparer.OrdinalIgnoreCase) - ?? ImmutableDictionary.Empty; + if (Features == features) + { + return this; + } + + if (features is not ImmutableDictionary dictionary || dictionary.KeyComparer != StringComparer.OrdinalIgnoreCase) + { + dictionary = (features ?? []).ToImmutableDictionary(StringComparer.OrdinalIgnoreCase); + } return new CSharpParseOptions(this) { _features = dictionary }; } diff --git a/src/roslyn/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/roslyn/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs index b9f8452c5a4..e77cf92a40e 100644 --- a/src/roslyn/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs +++ b/src/roslyn/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs @@ -6598,7 +6598,7 @@ private TypeWithState VisitAndCheckReceiver(BoundExpression? receiverOpt, Method } private (MethodSymbol method, ImmutableArray results, bool returnNotNull) ReInferMethodAndVisitArguments( - BoundExpression node, + BoundNode node, BoundExpression? receiverOpt, TypeWithState receiverType, MethodSymbol method, @@ -6615,7 +6615,7 @@ private TypeWithState VisitAndCheckReceiver(BoundExpression? receiverOpt, Method refKindsOpt = GetArgumentRefKinds(refKindsOpt, adjustForNewExtension, method, arguments.Length); - if (!receiverType.HasNullType) + if (!method.GetIsNewExtensionMember() && !receiverType.HasNullType) { // Update method based on inferred receiver type. method = (MethodSymbol)AsMemberOfType(receiverType.Type, method); @@ -7094,17 +7094,11 @@ private static TypeWithAnnotations ApplyUnconditionalAnnotations(TypeWithAnnotat // invocation (such as a synthesized call from a query interpretation). private static bool HasImplicitTypeArguments(BoundNode node) { - if (node is BoundCollectionElementInitializer { AddMethod: { TypeArgumentsWithAnnotations: { IsEmpty: false } } }) - { - return true; - } - - if (node is BoundForEachStatement { EnumeratorInfoOpt: { GetEnumeratorInfo: { Method: { TypeArgumentsWithAnnotations: { IsEmpty: false } } } } }) - { - return true; - } - - if (node is BoundPropertyAccess or BoundIncrementOperator or BoundCompoundAssignmentOperator) + if (node is BoundCollectionElementInitializer + or BoundForEachStatement + or BoundPropertyAccess + or BoundIncrementOperator + or BoundCompoundAssignmentOperator) { return true; } @@ -8662,6 +8656,8 @@ private TypeWithState GetAdjustedResult(TypeWithState type, int slot) private static Symbol AsMemberOfType(TypeSymbol? type, Symbol symbol) { Debug.Assert((object)symbol != null); + // https://github.com/dotnet/roslyn/issues/78828: This method should not be used with new extension members. + //Debug.Assert(!symbol.GetIsNewExtensionMember()); var containingType = type as NamedTypeSymbol; if (containingType is null || containingType.IsErrorType() || symbol is ErrorMethodSymbol) @@ -11586,25 +11582,28 @@ private void VisitForEachExpression( MethodSymbol? reinferredGetEnumeratorMethod = null; - if (enumeratorInfoOpt?.GetEnumeratorInfo is { Method: { IsExtensionMethod: true, Parameters: var parameters } } enumeratorMethodInfo) // Tracked by https://github.com/dotnet/roslyn/issues/78828: Test this code path with new extensions + if (enumeratorInfoOpt?.GetEnumeratorInfo is { } enumeratorMethodInfo + && (enumeratorMethodInfo.Method.IsExtensionMethod || enumeratorMethodInfo.Method.GetIsNewExtensionMember())) { // this is case 7 // We do not need to do this same analysis for non-extension methods because they do not have generic parameters that // can be inferred from usage like extension methods can. We don't warn about default arguments at the call site, so // there's nothing that can be learned from the non-extension case. - var (method, results, _) = VisitArguments( - node, - enumeratorMethodInfo.Arguments, + (reinferredGetEnumeratorMethod, var results, _) = ReInferMethodAndVisitArguments( + node: node, + receiverOpt: expr, + receiverType: resultTypeWithState, + method: enumeratorMethodInfo.Method, + arguments: enumeratorMethodInfo.Arguments, refKindsOpt: default, - parameters, argsToParamsOpt: default, defaultArguments: enumeratorMethodInfo.DefaultArguments, expanded: enumeratorMethodInfo.Expanded, invokedAsExtensionMethod: true, - enumeratorMethodInfo.Method); + suppressAdjustmentForNewExtension: false, + firstArgumentResult: _visitResult); targetTypeWithAnnotations = results[0].LValueType; - reinferredGetEnumeratorMethod = method; } else if (conversion.IsIdentity || (conversion.Kind == ConversionKind.ExplicitReference && resultType.SpecialType == SpecialType.System_String)) @@ -11633,12 +11632,14 @@ private void VisitForEachExpression( { // This is case 8. There was not a successful binding, as a successful binding will _always_ generate one of the // above conversions. Just return, as we want to suppress further errors. + Debug.Assert(node.HasErrors); return; } } else { // This is also case 8. + Debug.Assert(node.HasErrors); return; } @@ -11653,7 +11654,8 @@ private void VisitForEachExpression( useLegacyWarnings: false, AssignmentKind.Assignment); - bool reportedDiagnostic = enumeratorInfoOpt?.GetEnumeratorInfo.Method is { IsExtensionMethod: true } // Tracked by https://github.com/dotnet/roslyn/issues/78828: Test this code path with new extensions + bool reportedDiagnostic = enumeratorInfoOpt?.GetEnumeratorInfo.Method is { } getEnumeratorMethod + && (getEnumeratorMethod.IsExtensionMethod || getEnumeratorMethod.GetIsNewExtensionMember()) ? false : CheckPossibleNullReceiver(expr); diff --git a/src/roslyn/src/Compilers/CSharp/Portable/Lowering/ExtensionMethodReferenceRewriter.cs b/src/roslyn/src/Compilers/CSharp/Portable/Lowering/ExtensionMethodReferenceRewriter.cs index e718340a931..3aa43a2359d 100644 --- a/src/roslyn/src/Compilers/CSharp/Portable/Lowering/ExtensionMethodReferenceRewriter.cs +++ b/src/roslyn/src/Compilers/CSharp/Portable/Lowering/ExtensionMethodReferenceRewriter.cs @@ -168,6 +168,8 @@ static RefKind argumentRefKindFromReceiverRefKind(RefKind receiverRefKind) Debug.Assert(method?.GetIsNewExtensionMember() != true || method.OriginalDefinition.TryGetCorrespondingExtensionImplementationMethod() is null); // All possibly interesting methods should go through VisitMethodSymbolWithExtensionRewrite first + + /* Debug.Assert(method is null || method.ContainingSymbol is not NamedTypeSymbol || method.MethodKind is (MethodKind.Constructor or MethodKind.StaticConstructor) || @@ -185,6 +187,7 @@ method.OriginalDefinition is ErrorMethodSymbol || { Name: nameof(VisitMethodSymbolWithExtensionRewrite), DeclaringType: { } declaringType } => declaringType == typeof(ExtensionMethodReferenceRewriter), _ => false }); + */ return base.VisitMethodSymbol(method); } diff --git a/src/roslyn/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs b/src/roslyn/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs index 0acffc55fc7..f873604e966 100644 --- a/src/roslyn/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs +++ b/src/roslyn/src/Compilers/CSharp/Test/CommandLine/CommandLineTests.cs @@ -8630,7 +8630,7 @@ public static int Main() CleanupAllGeneratedFiles(source); } - [Fact(), WorkItem(546025, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546025")] + [ConditionalFact(typeof(DesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/79351"), WorkItem(546025, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/546025")] public void TestWin32ResWithBadResFile_CS1583ERR_BadWin32Res_01() { string source = Temp.CreateFile(prefix: "", extension: ".cs").WriteAllText(@"class Test { static void Main() {} }").Path; diff --git a/src/roslyn/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs b/src/roslyn/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs index 12429fe1f83..29e1df3a942 100644 --- a/src/roslyn/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs +++ b/src/roslyn/src/Compilers/CSharp/Test/Emit3/Semantics/ExtensionTests.cs @@ -13073,7 +13073,63 @@ static class E Assert.Null(model.GetForEachStatementInfo(loop).CurrentProperty); } - [Fact] + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78828")] + public void InstanceMethodInvocation_PatternBased_ForEach_GetEnumerator_Conversion_Classic() + { + var src = """ +foreach (var x in new C()) +{ + System.Console.Write(x); + break; +} + +class C { } +class D +{ + public bool MoveNext() => true; + public int Current => 42; +} + +static class E +{ + public static D GetEnumerator(this object obj) => new D(); +} +"""; + var comp = CreateCompilation(src); + CompileAndVerify(comp, expectedOutput: "42").VerifyDiagnostics(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78828")] + public void Foreach_GetEnumerator_ReceiverNullableWarning() + { + var src = """ +#nullable enable + +foreach (var x in ((C?)null).Id()) // 1 +{ +} + +class C +{ + public C Id() => this; +} + +static class E +{ + extension(C c) + { + public System.Collections.Generic.IEnumerator GetEnumerator() => throw null!; + } +} +"""; + var comp = CreateCompilation(src); + comp.VerifyEmitDiagnostics( + // (3,20): warning CS8602: Dereference of a possibly null reference. + // foreach (var x in ((C?)null).Id()) // 1 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "(C?)null").WithLocation(3, 20)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78828")] public void InstanceMethodInvocation_PatternBased_ForEach_GetEnumerator_Conversion() { var src = """ @@ -13098,15 +13154,110 @@ static class E } } """; - try - { - // Tracked by https://github.com/dotnet/roslyn/issues/78828 : assertion in NullableWalker - var comp = CreateCompilation(src); - CompileAndVerify(comp, expectedOutput: "42").VerifyDiagnostics(); - } - catch (InvalidOperationException) - { - } + var comp = CreateCompilation(src); + CompileAndVerify(comp, expectedOutput: "42").VerifyDiagnostics(); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78828")] + public void ExtensionGetEnumerator_NullReceiver() + { + var src = """ + #nullable enable + C? c = null; + foreach (var x in c) // 1 + { + System.Console.Write(x); + break; + } + + class C + { + } + + static class E + { + extension(C c) + { + public System.Collections.Generic.IEnumerator GetEnumerator() => throw null!; + } + } + """; + var comp = CreateCompilation(src); + // Tracked by https://github.com/dotnet/roslyn/issues/78830 : diagnostic quality consider reporting a better containing symbol + comp.VerifyEmitDiagnostics( + // (3,19): warning CS8604: Possible null reference argument for parameter 'c' in 'extension(C)'. + // foreach (var x in c) // 1 + Diagnostic(ErrorCode.WRN_NullReferenceArgument, "c").WithArguments("c", "extension(C)").WithLocation(3, 19)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78828")] + public void ExtensionGetEnumerator_NullReceiver_Classic() + { + var src = """ + #nullable enable + C? c = null; + foreach (var x in c) // 1 + { + System.Console.Write(x); + break; + } + + class C + { + } + + static class E + { + public static System.Collections.Generic.IEnumerator GetEnumerator(this C c) => throw null!; + } + """; + var comp = CreateCompilation(src); + comp.VerifyEmitDiagnostics( + // (3,19): warning CS8604: Possible null reference argument for parameter 'c' in 'IEnumerator E.GetEnumerator(C c)'. + // foreach (var x in c) // 1 + Diagnostic(ErrorCode.WRN_NullReferenceArgument, "c").WithArguments("c", "IEnumerator E.GetEnumerator(C c)").WithLocation(3, 19)); + } + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78828")] + public void ExtensionGetEnumerator_Reinference() + { + var src = """ + #nullable enable + var s = "a"; + if (string.Empty == "") + s = null; + + var c = M(s); // 'C' + foreach (var x in c) + { + x.ToString(); // 1 + } + + var d = M("a"); // 'C' + foreach (var x in d) + { + x.ToString(); // ok + } + + C M(T item) => throw null!; + + class C + { + } + + static class E + { + extension(C c) + { + public System.Collections.Generic.IEnumerator GetEnumerator() => throw null!; + } + } + """; + var comp = CreateCompilation(src); + comp.VerifyEmitDiagnostics( + // (9,5): warning CS8602: Dereference of a possibly null reference. + // x.ToString(); // 1 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(9, 5)); } [Fact] @@ -35643,7 +35794,7 @@ public static class Extensions public C.Enumerator GetEnumerator(int x = 1) => new C.Enumerator(x); } }"; - var verifier = CompileAndVerify(source, expectedOutput: "23", parseOptions: TestOptions.RegularPreview.WithFeature("run-nullable-analysis", "never")); // Tracked by https://github.com/dotnet/roslyn/issues/78828: Nullable analysis asserts + var verifier = CompileAndVerify(source, expectedOutput: "23"); VerifyFlowGraphAndDiagnosticsForTest((CSharpCompilation)verifier.Compilation, @" @@ -42134,10 +42285,12 @@ public void Nullability_ForEach_01() using System.Collections.Generic; object? oNull = null; -foreach (var x in oNull) { x.ToString(); } +foreach (var x in oNull) + x.ToString(); // 1 object? oNotNull = new object(); -foreach (var y in oNotNull) { y.ToString(); } +foreach (var y in oNotNull) + y.ToString(); static class E { @@ -42152,9 +42305,9 @@ public IEnumerator GetEnumerator() """; var comp = CreateCompilation(src); comp.VerifyEmitDiagnostics( - // (5,19): warning CS8602: Dereference of a possibly null reference. - // foreach (var x in oNull) { x.ToString(); } - Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "oNull").WithLocation(5, 19)); + // (6,5): warning CS8602: Dereference of a possibly null reference. + // x.ToString(); // 1 + Diagnostic(ErrorCode.WRN_NullReferenceReceiver, "x").WithLocation(6, 5)); var tree = comp.SyntaxTrees.Single(); var model = comp.GetSemanticModel(tree); diff --git a/src/roslyn/src/Compilers/CSharp/Test/Syntax/Parsing/CSharpParseOptionsTests.cs b/src/roslyn/src/Compilers/CSharp/Test/Syntax/Parsing/CSharpParseOptionsTests.cs index 95acc81fd07..f050cdf9b6e 100644 --- a/src/roslyn/src/Compilers/CSharp/Test/Syntax/Parsing/CSharpParseOptionsTests.cs +++ b/src/roslyn/src/Compilers/CSharp/Test/Syntax/Parsing/CSharpParseOptionsTests.cs @@ -45,10 +45,23 @@ public void WithXxx() TestProperty((old, value) => old.WithLanguageVersion(value), opt => opt.LanguageVersion, LanguageVersion.CSharp3); TestProperty((old, value) => old.WithDocumentationMode(value), opt => opt.DocumentationMode, DocumentationMode.None); TestProperty((old, value) => old.WithPreprocessorSymbols(value), opt => opt.PreprocessorSymbols, ImmutableArray.Create("A", "B", "C")); + } + + [Fact] + public void WithPreprocessorSymbols() + { + Assert.Equal(0, CSharpParseOptions.Default.WithPreprocessorSymbols(ImmutableArray.Create("A", "B")).WithPreprocessorSymbols(default(ImmutableArray)).PreprocessorSymbols.Length); + Assert.Equal(0, CSharpParseOptions.Default.WithPreprocessorSymbols(ImmutableArray.Create("A", "B")).WithPreprocessorSymbols((IEnumerable)null).PreprocessorSymbols.Length); + Assert.Equal(0, CSharpParseOptions.Default.WithPreprocessorSymbols(ImmutableArray.Create("A", "B")).WithPreprocessorSymbols((string[])null).PreprocessorSymbols.Length); + } - Assert.Equal(0, CSharpParseOptions.Default.WithPreprocessorSymbols(ImmutableArray.Create("A", "B")).WithPreprocessorSymbols(default(ImmutableArray)).PreprocessorSymbols.Length); - Assert.Equal(0, CSharpParseOptions.Default.WithPreprocessorSymbols(ImmutableArray.Create("A", "B")).WithPreprocessorSymbols((IEnumerable)null).PreprocessorSymbols.Length); - Assert.Equal(0, CSharpParseOptions.Default.WithPreprocessorSymbols(ImmutableArray.Create("A", "B")).WithPreprocessorSymbols((string[])null).PreprocessorSymbols.Length); + [Fact] + public void WithFeatures() + { + var options1 = CSharpParseOptions.Default.WithFeatures(new Dictionary() { { "F1", "V1" }, { "F2", "V2" } }); + var options2 = CSharpParseOptions.Default.WithFeatures(new Dictionary() { { "f2", "V2" }, { "F1", "V1" } }); + + Assert.True(options1.Equals(options2)); } /// diff --git a/src/roslyn/src/Compilers/Core/CodeAnalysisTest/AnalyzerAssemblyLoaderTests.cs b/src/roslyn/src/Compilers/Core/CodeAnalysisTest/AnalyzerAssemblyLoaderTests.cs index a21427abe5c..201ce70c0cc 100644 --- a/src/roslyn/src/Compilers/Core/CodeAnalysisTest/AnalyzerAssemblyLoaderTests.cs +++ b/src/roslyn/src/Compilers/Core/CodeAnalysisTest/AnalyzerAssemblyLoaderTests.cs @@ -1160,7 +1160,7 @@ public void AssemblyLoading_MultipleVersions_MissingVersion(AnalyzerTestKind kin /// Test the case where a utility is loaded by multiple analyzers at different versions. Ensure that no matter /// what order we load the analyzers we correctly resolve the utility version. /// - [Theory] + [ConditionalTheory(typeof(DesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/79352")] [CombinatorialData] public void AssemblyLoading_MultipleVersions_AnalyzerDependency(AnalyzerTestKind kind, bool normalOrder) { diff --git a/src/roslyn/src/Compilers/Core/CodeAnalysisTest/CompilerResolverTests.cs b/src/roslyn/src/Compilers/Core/CodeAnalysisTest/CompilerResolverTests.cs index 546546ba3f6..e47630d984c 100644 --- a/src/roslyn/src/Compilers/Core/CodeAnalysisTest/CompilerResolverTests.cs +++ b/src/roslyn/src/Compilers/Core/CodeAnalysisTest/CompilerResolverTests.cs @@ -4,10 +4,12 @@ #if NET using System; +using System.Collections.Immutable; using System.Linq; using System.Reflection; using System.Runtime.Loader; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; @@ -16,7 +18,7 @@ namespace Microsoft.CodeAnalysis.UnitTests; public sealed class CompilerResolverTests : IDisposable { public TempRoot TempRoot { get; } - public int DefaultLoadContextCount { get; } + public ImmutableArray DefaultLoadContextAssemblies { get; } public AssemblyLoadContext CompilerContext { get; } public AssemblyLoadContext ScratchContext { get; } public Assembly AssemblyInCompilerContext { get; } @@ -25,7 +27,7 @@ public sealed class CompilerResolverTests : IDisposable public CompilerResolverTests() { TempRoot = new TempRoot(); - DefaultLoadContextCount = AssemblyLoadContext.Default.Assemblies.Count(); + DefaultLoadContextAssemblies = AssemblyLoadContext.Default.Assemblies.SelectAsArray(a => a.FullName); CompilerContext = new AssemblyLoadContext(nameof(CompilerResolverTests), isCollectible: true); AssemblyInCompilerContext = CompilerContext.LoadFromAssemblyPath(typeof(AnalyzerAssemblyLoader).Assembly.Location); ScratchContext = new AssemblyLoadContext("Scratch", isCollectible: true); @@ -35,7 +37,7 @@ public CompilerResolverTests() public void Dispose() { // This test should not pollute the default load context and hence interfere with other tests. - Assert.Equal(DefaultLoadContextCount, AssemblyLoadContext.Default.Assemblies.Count()); + AssertEx.SetEqual(DefaultLoadContextAssemblies, AssemblyLoadContext.Default.Assemblies.SelectAsArray(a => a.FullName)); CompilerContext.Unload(); ScratchContext.Unload(); TempRoot.Dispose(); @@ -49,7 +51,7 @@ public void ResolveReturnsNullForNonHostAssembly() Assert.Null(assembly); } - [Fact] + [ConditionalFact(typeof(DesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/79352")] public void ResolveReturnsForHostAssembly() { var assembly = Loader.CompilerAnalyzerAssemblyResolver.Resolve(Loader, AssemblyInCompilerContext.GetName(), ScratchContext, TempRoot.CreateDirectory().Path); diff --git a/src/roslyn/src/Compilers/Core/CodeAnalysisTest/InvokeUtil.cs b/src/roslyn/src/Compilers/Core/CodeAnalysisTest/InvokeUtil.cs index a7879283bce..408434fc7e3 100644 --- a/src/roslyn/src/Compilers/Core/CodeAnalysisTest/InvokeUtil.cs +++ b/src/roslyn/src/Compilers/Core/CodeAnalysisTest/InvokeUtil.cs @@ -63,7 +63,7 @@ internal void Exec( } var loader = new AnalyzerAssemblyLoader(pathResolvers, assemblyResolvers, compilerLoadContext: null); - var compilerContextAssemblyCount = loader.CompilerLoadContext.Assemblies.Count(); + var compilerContextAssemblies = loader.CompilerLoadContext.Assemblies.SelectAsArray(a => a.FullName); try { Exec(testOutputHelper, fixture, loader, typeName, methodName, state); @@ -72,7 +72,7 @@ internal void Exec( { // When using the actual compiler load context (the one shared by all of our unit tests) the test // did not load any additional assemblies that could interfere with later tests. - Assert.Equal(compilerContextAssemblyCount, loader.CompilerLoadContext.Assemblies.Count()); + AssertEx.SetEqual(compilerContextAssemblies, loader.CompilerLoadContext.Assemblies.SelectAsArray(a => a.FullName)); } } @@ -89,7 +89,7 @@ internal void Exec( // load into the compiler or directory load context. // // Not only is this bad behavior it also pollutes future test results. - var defaultContextCount = AssemblyLoadContext.Default.Assemblies.Count(); + var defaultContextAssemblies = AssemblyLoadContext.Default.Assemblies.SelectAsArray(a => a.FullName); using var tempRoot = new TempRoot(); try @@ -120,7 +120,7 @@ internal void Exec( testOutputHelper.WriteLine($"\t{pair.OriginalAssemblyPath} -> {pair.ResolvedAssemblyPath}"); } - Assert.Equal(defaultContextCount, AssemblyLoadContext.Default.Assemblies.Count()); + AssertEx.SetEqual(defaultContextAssemblies, AssemblyLoadContext.Default.Assemblies.SelectAsArray(a => a.FullName)); } } } diff --git a/src/roslyn/src/Compilers/Core/Portable/Compilation/ParseOptions.cs b/src/roslyn/src/Compilers/Core/Portable/Compilation/ParseOptions.cs index 51aa13c8191..1e0377a8382 100644 --- a/src/roslyn/src/Compilers/Core/Portable/Compilation/ParseOptions.cs +++ b/src/roslyn/src/Compilers/Core/Portable/Compilation/ParseOptions.cs @@ -141,7 +141,7 @@ protected bool EqualsHelper([NotNullWhen(true)] ParseOptions? other) return this.SpecifiedKind == other.SpecifiedKind && this.DocumentationMode == other.DocumentationMode && - this.Features.SequenceEqual(other.Features) && + FeaturesEqual(Features, other.Features) && (this.PreprocessorSymbolNames == null ? other.PreprocessorSymbolNames == null : this.PreprocessorSymbolNames.SequenceEqual(other.PreprocessorSymbolNames, StringComparer.Ordinal)); } @@ -156,6 +156,29 @@ protected int GetHashCodeHelper() Hash.Combine(Hash.CombineValues(this.PreprocessorSymbolNames, StringComparer.Ordinal), 0)))); } + private static bool FeaturesEqual(IReadOnlyDictionary features, IReadOnlyDictionary other) + { + if (ReferenceEquals(features, other)) + { + return true; + } + + if (features.Count != other.Count) + { + return false; + } + + foreach (var (key, value) in features) + { + if (!other.TryGetValue(key, out var otherValue) || value != otherValue) + { + return false; + } + } + + return true; + } + private static int HashFeatures(IReadOnlyDictionary features) { int value = 0; diff --git a/src/roslyn/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenWithEvents.vb b/src/roslyn/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenWithEvents.vb index d72ff6403a9..3eed68c69a7 100644 --- a/src/roslyn/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenWithEvents.vb +++ b/src/roslyn/src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenWithEvents.vb @@ -10,7 +10,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests Public Class CodeGenWithEvents Inherits BasicTestBase - + Public Sub SimpleWithEventsTest() Dim compilation1 = CompileAndVerify( @@ -400,7 +400,7 @@ handled1 End Sub - + Public Sub SimpleSharedWithEvents() Dim compilation1 = CompileAndVerify( @@ -2003,7 +2003,7 @@ End Class CompileAndVerify(source) End Sub - + Public Sub MultipleInitializationsWithAsNew_01() Dim source = @@ -2067,7 +2067,7 @@ False ]]>) End Sub - + Public Sub MultipleInitializationsWithAsNew_02() Dim source = diff --git a/src/roslyn/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb b/src/roslyn/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb index bcc4cbcb6bb..daec12f553a 100644 --- a/src/roslyn/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb +++ b/src/roslyn/src/Compilers/VisualBasic/Test/Symbol/SymbolsTests/Retargeting/RetargetingTests.vb @@ -1962,7 +1962,7 @@ MethodOverload(Base) End Sub - + Public Sub Retarget_Events() 'The test involves compilation with/without retargeting and ensuring same behavior at runtime 'same diagnostics (or lack off) as compile time diff --git a/src/roslyn/src/EditorFeatures/Core/Shared/Tagging/EventSources/TaggerEventSources.DocumentActiveContextChangedEventSource.cs b/src/roslyn/src/EditorFeatures/Core/Shared/Tagging/EventSources/TaggerEventSources.DocumentActiveContextChangedEventSource.cs index ce3dc9480a1..ee02ce7ef6c 100644 --- a/src/roslyn/src/EditorFeatures/Core/Shared/Tagging/EventSources/TaggerEventSources.DocumentActiveContextChangedEventSource.cs +++ b/src/roslyn/src/EditorFeatures/Core/Shared/Tagging/EventSources/TaggerEventSources.DocumentActiveContextChangedEventSource.cs @@ -13,8 +13,9 @@ private sealed class DocumentActiveContextChangedEventSource(ITextBuffer subject { private WorkspaceEventRegistration? _documentActiveContextChangedDisposer; + // Require main thread on the callback as RaiseChanged implementors may have main thread dependencies. protected override void ConnectToWorkspace(Workspace workspace) - => _documentActiveContextChangedDisposer = workspace.RegisterDocumentActiveContextChangedHandler(OnDocumentActiveContextChanged); + => _documentActiveContextChangedDisposer = workspace.RegisterDocumentActiveContextChangedHandler(OnDocumentActiveContextChanged, WorkspaceEventOptions.RequiresMainThreadOptions); protected override void DisconnectFromWorkspace(Workspace workspace) => _documentActiveContextChangedDisposer?.Dispose(); diff --git a/src/roslyn/src/EditorFeatures/Core/Tagging/ITaggerEventSource.cs b/src/roslyn/src/EditorFeatures/Core/Tagging/ITaggerEventSource.cs index 5bc6e17c726..1a8e1f613fe 100644 --- a/src/roslyn/src/EditorFeatures/Core/Tagging/ITaggerEventSource.cs +++ b/src/roslyn/src/EditorFeatures/Core/Tagging/ITaggerEventSource.cs @@ -41,7 +41,7 @@ internal interface ITaggerEventSource /// /// An event has happened on the thing the tagger is attached to. The tagger should - /// recompute tags. May be raised on any thread. + /// recompute tags. /// event EventHandler Changed; } diff --git a/src/roslyn/src/EditorFeatures/XunitHook/XunitDisposeHook.cs b/src/roslyn/src/EditorFeatures/XunitHook/XunitDisposeHook.cs index 96297521040..9aaf3668028 100644 --- a/src/roslyn/src/EditorFeatures/XunitHook/XunitDisposeHook.cs +++ b/src/roslyn/src/EditorFeatures/XunitHook/XunitDisposeHook.cs @@ -18,7 +18,7 @@ public void Execute() if (!AppDomain.CurrentDomain.IsDefaultAppDomain()) throw new InvalidOperationException(); - var xunitUtilities = AppDomain.CurrentDomain.GetAssemblies().Where(static assembly => assembly.GetName().Name.StartsWith("xunit.runner.utility")).ToArray(); + var xunitUtilities = AppDomain.CurrentDomain.GetAssemblies().Where(static assembly => assembly.GetName().Name.StartsWith("xunit.runner.visualstudio")).ToArray(); foreach (var xunitUtility in xunitUtilities) { var appDomainManagerType = xunitUtility.GetType("Xunit.AppDomainManager_AppDomain"); diff --git a/src/roslyn/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs b/src/roslyn/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs index 9794ced6bf2..13de4a97b56 100644 --- a/src/roslyn/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs +++ b/src/roslyn/src/Features/CSharp/Portable/EditAndContinue/CSharpEditAndContinueAnalyzer.cs @@ -3074,4 +3074,29 @@ private static bool DeclareSameIdentifiers(SyntaxToken[] oldVariables, SyntaxTok } #endregion + + protected override IEnumerable GetParseOptionsRudeEdits(ParseOptions oldOptions, ParseOptions newOptions) + { + foreach (var rudeEdit in base.GetParseOptionsRudeEdits(oldOptions, newOptions)) + { + yield return rudeEdit; + } + + var oldCSharpOptions = (CSharpParseOptions)oldOptions; + var newCSharpOptions = (CSharpParseOptions)newOptions; + + if (oldCSharpOptions.LanguageVersion != newCSharpOptions.LanguageVersion) + { + yield return CreateProjectRudeEdit(ProjectSettingKind.LangVersion, + oldCSharpOptions.SpecifiedLanguageVersion.ToDisplayString(), + newCSharpOptions.SpecifiedLanguageVersion.ToDisplayString()); + } + + if (!oldCSharpOptions.PreprocessorSymbolNames.SequenceEqual(newCSharpOptions.PreprocessorSymbolNames, StringComparer.Ordinal)) + { + yield return CreateProjectRudeEdit(ProjectSettingKind.DefineConstants, + string.Join(",", oldCSharpOptions.PreprocessorSymbolNames), + string.Join(",", newCSharpOptions.PreprocessorSymbolNames)); + } + } } diff --git a/src/roslyn/src/Features/CSharpTest/EditAndContinue/CSharpEditAndContinueAnalyzerTests.cs b/src/roslyn/src/Features/CSharpTest/EditAndContinue/CSharpEditAndContinueAnalyzerTests.cs index 046a9fd0a91..fc37e62f148 100644 --- a/src/roslyn/src/Features/CSharpTest/EditAndContinue/CSharpEditAndContinueAnalyzerTests.cs +++ b/src/roslyn/src/Features/CSharpTest/EditAndContinue/CSharpEditAndContinueAnalyzerTests.cs @@ -368,8 +368,9 @@ public static void Main() var result = await AnalyzeDocumentAsync(oldProject, newSolution.GetDocument(documentId)); Assert.True(result.HasChanges); - Assert.True(result.HasChangesAndErrors); - Assert.True(result.HasChangesAndSyntaxErrors); + Assert.True(result.AnalysisBlocked); + Assert.NotNull(result.SyntaxError); + Assert.False(result.HasBlockingRudeEdits); } [Fact] @@ -393,8 +394,9 @@ public static void Main() var result = await AnalyzeDocumentAsync(oldProject, oldDocument); Assert.False(result.HasChanges); - Assert.False(result.HasChangesAndErrors); - Assert.False(result.HasChangesAndSyntaxErrors); + Assert.False(result.AnalysisBlocked); + Assert.Null(result.SyntaxError); + Assert.False(result.HasBlockingRudeEdits); } [Fact] @@ -430,8 +432,9 @@ public static void Main() var result = await AnalyzeDocumentAsync(oldProject, newSolution.GetDocument(documentId)); Assert.False(result.HasChanges); - Assert.False(result.HasChangesAndErrors); - Assert.False(result.HasChangesAndSyntaxErrors); + Assert.False(result.AnalysisBlocked); + Assert.Null(result.SyntaxError); + Assert.False(result.HasBlockingRudeEdits); } [Fact] @@ -462,8 +465,9 @@ public static void Main() var result = await AnalyzeDocumentAsync(oldProject, oldDocument); Assert.False(result.HasChanges); - Assert.False(result.HasChangesAndErrors); - Assert.False(result.HasChangesAndSyntaxErrors); + Assert.False(result.AnalysisBlocked); + Assert.False(result.HasBlockingRudeEdits); + Assert.Null(result.SyntaxError); Assert.True(result.RudeEdits.IsEmpty); } @@ -510,8 +514,8 @@ public static void Main() var result = await AnalyzeDocumentAsync(oldProject, newSolution.GetDocument(documentId)); Assert.True(result.HasChanges); - Assert.True(result.HasChangesAndErrors); - Assert.False(result.HasChangesAndSyntaxErrors); + Assert.True(result.AnalysisBlocked); + Assert.False(result.HasBlockingRudeEdits); Assert.Equal(RudeEditKind.ExperimentalFeaturesEnabled, result.RudeEdits.Single().Kind); } } @@ -540,8 +544,9 @@ public static void Main() var result = await AnalyzeDocumentAsync(oldProject, oldDocument); Assert.False(result.HasChanges); - Assert.False(result.HasChangesAndErrors); - Assert.False(result.HasChangesAndSyntaxErrors); + Assert.False(result.HasBlockingRudeEdits); + Assert.False(result.AnalysisBlocked); + Assert.Null(result.SyntaxError); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/10683")] @@ -581,8 +586,9 @@ public static void Main() Assert.True(result.HasChanges); // no declaration errors (error in method body is only reported when emitting): - Assert.False(result.HasChangesAndErrors); - Assert.False(result.HasChangesAndSyntaxErrors); + Assert.False(result.HasBlockingRudeEdits); + Assert.False(result.AnalysisBlocked); + Assert.Null(result.SyntaxError); } [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/10683")] @@ -621,8 +627,8 @@ public static void Main(Bar x) // No errors reported: EnC analyzer is resilient against semantic errors. // They will be reported by 1) compiler diagnostic analyzer 2) when emitting delta - if still present. - Assert.False(result.HasChangesAndErrors); - Assert.False(result.HasChangesAndSyntaxErrors); + Assert.False(result.AnalysisBlocked); + Assert.False(result.HasBlockingRudeEdits); } [Fact] diff --git a/src/roslyn/src/Features/CSharpTest/ImplementInterface/ImplementInterfaceCodeRefactoringTests.cs b/src/roslyn/src/Features/CSharpTest/ImplementInterface/ImplementInterfaceCodeRefactoringTests.cs new file mode 100644 index 00000000000..820dbc26a4f --- /dev/null +++ b/src/roslyn/src/Features/CSharpTest/ImplementInterface/ImplementInterfaceCodeRefactoringTests.cs @@ -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. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; +using Microsoft.CodeAnalysis.ImplementInterface; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests.ImplementInterface; + +using VerifyCS = CSharpCodeRefactoringVerifier< + ImplementInterfaceCodeRefactoringProvider>; + +[UseExportProvider] +[Trait(Traits.Feature, Traits.Features.CodeActionsImplementInterface)] +public sealed class ImplementInterfaceCodeRefactoringTests +{ + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78294")] + public Task TestInBody() + => VerifyCS.VerifyRefactoringAsync(""" + interface IGoo + { + void Goo(); + } + + class C : {|CS0535:IGoo|} + { + $$ + } + """, """ + interface IGoo + { + void Goo(); + } + + class C : IGoo + { + public void Goo() + { + throw new System.NotImplementedException(); + } + } + """); + + [Fact, WorkItem("https://github.com/dotnet/roslyn/issues/78294")] + public Task TestNotOnInterfaceInBody() + => VerifyCS.VerifyRefactoringAsync(""" + interface IGoo + { + void Goo(); + } + + interface IBar : IGoo + { + $$ + } + """); +} diff --git a/src/roslyn/src/Features/Core/Portable/CodeRefactorings/PredefinedCodeRefactoringProviderNames.cs b/src/roslyn/src/Features/Core/Portable/CodeRefactorings/PredefinedCodeRefactoringProviderNames.cs index c6e7daf484e..47c3cd2a86a 100644 --- a/src/roslyn/src/Features/Core/Portable/CodeRefactorings/PredefinedCodeRefactoringProviderNames.cs +++ b/src/roslyn/src/Features/Core/Portable/CodeRefactorings/PredefinedCodeRefactoringProviderNames.cs @@ -47,6 +47,7 @@ internal static class PredefinedCodeRefactoringProviderNames public const string GenerateConstructorFromMembers = "Generate Constructor From Members Code Action Provider"; public const string GenerateEqualsAndGetHashCodeFromMembers = "Generate Equals and GetHashCode Code Action Provider"; public const string GenerateOverrides = "Generate Overrides Code Action Provider"; + public const string ImplementInterface = nameof(ImplementInterface); public const string ImplementInterfaceExplicitly = nameof(ImplementInterfaceExplicitly); public const string ImplementInterfaceImplicitly = nameof(ImplementInterfaceImplicitly); public const string InitializeMemberFromParameter = nameof(InitializeMemberFromParameter); diff --git a/src/roslyn/src/Features/Core/Portable/Diagnostics/CodeAnalysisDiagnosticAnalyzerService.cs b/src/roslyn/src/Features/Core/Portable/Diagnostics/CodeAnalysisDiagnosticAnalyzerService.cs index 9fbca617af8..62ccb84a89d 100644 --- a/src/roslyn/src/Features/Core/Portable/Diagnostics/CodeAnalysisDiagnosticAnalyzerService.cs +++ b/src/roslyn/src/Features/Core/Portable/Diagnostics/CodeAnalysisDiagnosticAnalyzerService.cs @@ -49,7 +49,9 @@ public CodeAnalysisDiagnosticAnalyzerService( _workspace = workspace; _diagnosticAnalyzerService = _workspace.Services.GetRequiredService(); - _ = workspace.RegisterWorkspaceChangedHandler(OnWorkspaceChanged); + // Main thread as OnWorkspaceChanged's call to IDiagnosticAnalyzerService.RequestDiagnosticRefresh isn't clear on + // threading requirements + _ = workspace.RegisterWorkspaceChangedHandler(OnWorkspaceChanged, WorkspaceEventOptions.RequiresMainThreadOptions); } private void OnWorkspaceChanged(WorkspaceChangeEventArgs e) diff --git a/src/roslyn/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs b/src/roslyn/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs index 52e6bb235e3..77381fe91a7 100644 --- a/src/roslyn/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs +++ b/src/roslyn/src/Features/Core/Portable/Diagnostics/IDiagnosticAnalyzerService.cs @@ -22,9 +22,6 @@ internal interface IDiagnosticAnalyzerService : IWorkspaceService /// /// Re-analyze all projects and documents. This will cause an LSP diagnostic refresh request to be sent. /// - /// - /// This implementation must be safe to call on any thread. - /// void RequestDiagnosticRefresh(); /// diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs index 9e6c0d9456a..c2630e369f7 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/AbstractEditAndContinueAnalyzer.cs @@ -561,7 +561,7 @@ public async Task AnalyzeDocumentAsync( // Bail, since we can't do syntax diffing on broken trees (it would not produce useful results anyways). // If we needed to do so for some reason, we'd need to harden the syntax tree comparers. log.Write($"Syntax errors found in '{filePath}'"); - return DocumentAnalysisResults.SyntaxErrors(documentId, filePath, [], syntaxError, analysisStopwatch.Elapsed, hasChanges); + return DocumentAnalysisResults.Blocked(documentId, filePath, [], syntaxError, analysisStopwatch.Elapsed, hasChanges); } // Disallow modification of a file with experimental features enabled. @@ -569,7 +569,21 @@ public async Task AnalyzeDocumentAsync( if (ExperimentalFeaturesEnabled(newTree)) { log.Write($"Experimental features enabled in '{filePath}'"); - return DocumentAnalysisResults.SyntaxErrors(documentId, filePath, [new RudeEditDiagnostic(RudeEditKind.ExperimentalFeaturesEnabled, default)], syntaxError: null, analysisStopwatch.Elapsed, hasChanges); + return DocumentAnalysisResults.Blocked(documentId, filePath, [new RudeEditDiagnostic(RudeEditKind.ExperimentalFeaturesEnabled, span: default)], syntaxError: null, analysisStopwatch.Elapsed, hasChanges); + } + + // Changes in parse options might change the meaning of the code even if nothing else changed. + // If we allowed changing parse options such as preprocessor directives, enabled features, or language version + // it would lead to degraded experience for the user -- the parts of the source file that haven't changed + // since the option changed would have different semantics than the parts that have changed. + // + // Skip further analysis of the document if we detect any such change (classified as rude edits) in parse options. + if (GetParseOptionsRudeEdits(oldTree.Options, newTree.Options).Any()) + { + log.Write($"Parse options differ for '{filePath}'"); + + // All rude edits related to project-level setting changes will be reported during delta emit. + return DocumentAnalysisResults.Blocked(documentId, filePath, rudeEdits: [], syntaxError: null, analysisStopwatch.Elapsed, hasChanges); } var capabilities = new EditAndContinueCapabilitiesGrantor(await lazyCapabilities.GetValueAsync(cancellationToken).ConfigureAwait(false)); @@ -578,14 +592,9 @@ public async Task AnalyzeDocumentAsync( // If the document has changed at all, lets make sure Edit and Continue is supported if (!capabilities.Grant(EditAndContinueCapabilities.Baseline)) { - return DocumentAnalysisResults.SyntaxErrors(documentId, filePath, [new RudeEditDiagnostic(RudeEditKind.NotSupportedByRuntime, default)], syntaxError: null, analysisStopwatch.Elapsed, hasChanges); + return DocumentAnalysisResults.Blocked(documentId, filePath, [new RudeEditDiagnostic(RudeEditKind.NotSupportedByRuntime, default)], syntaxError: null, analysisStopwatch.Elapsed, hasChanges); } - // TODO: https://github.com/dotnet/roslyn/issues/78486 - // Changes in parse options might change the meaning of the code even if nothing else changed. - // The IDE should disallow changing the options during debugging session. - Debug.Assert(oldTree.Options.Equals(newTree.Options)); - // We are in break state when there are no active statements. var inBreakState = !oldActiveStatementMap.IsEmpty; @@ -681,7 +690,7 @@ public async Task AnalyzeDocumentAsync( hasBlockingRudeEdits ? default : capabilities.GrantedCapabilities, analysisStopwatch.Elapsed, hasChanges: true, - hasSyntaxErrors: false, + analysisBlocked: false, hasBlockingRudeEdits); } catch (Exception e) when (FatalError.ReportAndCatchUnlessCanceled(e, cancellationToken)) @@ -694,8 +703,7 @@ public async Task AnalyzeDocumentAsync( ? new RudeEditDiagnostic(RudeEditKind.SourceFileTooBig, span: default, arguments: [filePath]) : new RudeEditDiagnostic(RudeEditKind.InternalError, span: default, arguments: [filePath, e.ToString()]); - // Report as "syntax error" - we can't analyze the document - return DocumentAnalysisResults.SyntaxErrors(documentId, filePath, [diagnostic], syntaxError: null, analysisStopwatch.Elapsed, hasChanges); + return DocumentAnalysisResults.Blocked(documentId, filePath, [diagnostic], syntaxError: null, analysisStopwatch.Elapsed, hasChanges); } void LogRudeEdits(ImmutableArray diagnostics, SourceText text, string filePath) @@ -817,6 +825,117 @@ internal Dictionary BuildEditMap(EditScript ed return map; } + protected static Diagnostic CreateProjectRudeEdit(ProjectSettingKind kind, string oldValue, string newValue) + => Diagnostic.Create( + EditAndContinueDiagnosticDescriptors.GetDescriptor(kind), + Location.None, + [kind.ToString(), oldValue, newValue]); + + protected virtual IEnumerable GetParseOptionsRudeEdits(ParseOptions oldOptions, ParseOptions newOptions) + { + if (!FeaturesEqual(oldOptions.Features, newOptions.Features)) + { + yield return CreateProjectRudeEdit(ProjectSettingKind.Features, ToDisplay(oldOptions.Features), ToDisplay(newOptions.Features)); + } + + static string ToDisplay(IReadOnlyDictionary features) + => string.Join(",", features.OrderBy(kvp => kvp.Key).Select(kvp => $"{kvp.Key}={kvp.Value}")); + + static bool FeaturesEqual(IReadOnlyDictionary features, IReadOnlyDictionary other) + { + if (ReferenceEquals(features, other)) + { + return true; + } + + if (features.Count != other.Count) + { + return false; + } + + foreach (var (key, value) in features) + { + if (!other.TryGetValue(key, out var otherValue) || value != otherValue) + { + return false; + } + } + + return true; + } + } + + protected static string DefaultProjectSettingValue + => $"<{FeaturesResources.@default}>"; + + protected virtual IEnumerable GetCompilationOptionsRudeEdits(CompilationOptions oldOptions, CompilationOptions newOptions) + { + if (oldOptions.CheckOverflow != newOptions.CheckOverflow) + { + yield return CreateProjectRudeEdit(ProjectSettingKind.CheckForOverflowUnderflow, oldOptions.CheckOverflow.ToString(), newOptions.CheckOverflow.ToString()); + } + + if (oldOptions.OutputKind != newOptions.OutputKind) + { + yield return CreateProjectRudeEdit(ProjectSettingKind.OutputType, ToProjectPropertyValue(oldOptions.OutputKind), ToProjectPropertyValue(newOptions.OutputKind)); + + static string ToProjectPropertyValue(OutputKind kind) + => kind switch + { + OutputKind.ConsoleApplication => "Exe", + OutputKind.WindowsApplication => "WinExe", + OutputKind.DynamicallyLinkedLibrary => "Library", + OutputKind.NetModule => "Module", + OutputKind.WindowsRuntimeApplication => "AppContainerExe", + OutputKind.WindowsRuntimeMetadata => "WinMDObj", + _ => throw ExceptionUtilities.UnexpectedValue(kind) + }; + } + + if (oldOptions.Platform != newOptions.Platform) + { + yield return CreateProjectRudeEdit(ProjectSettingKind.Platform, oldOptions.Platform.ToString(), newOptions.Platform.ToString()); + } + + if (oldOptions.MainTypeName != newOptions.MainTypeName) + { + yield return CreateProjectRudeEdit(ProjectSettingKind.StartupObject, oldOptions.MainTypeName ?? DefaultProjectSettingValue, newOptions.MainTypeName ?? DefaultProjectSettingValue); + } + + if (oldOptions.ModuleName != newOptions.ModuleName) + { + yield return CreateProjectRudeEdit(ProjectSettingKind.ModuleAssemblyName, oldOptions.ModuleName ?? DefaultProjectSettingValue, newOptions.ModuleName ?? DefaultProjectSettingValue); + } + + if (oldOptions.OptimizationLevel != newOptions.OptimizationLevel) + { + yield return CreateProjectRudeEdit(ProjectSettingKind.OptimizationLevel, oldOptions.OptimizationLevel.ToString(), newOptions.OptimizationLevel.ToString()); + } + } + + public IEnumerable GetProjectSettingRudeEdits(Project oldProject, Project newProject) + { + Contract.ThrowIfNull(oldProject.ParseOptions); + Contract.ThrowIfNull(newProject.ParseOptions); + Contract.ThrowIfNull(oldProject.CompilationOptions); + Contract.ThrowIfNull(newProject.CompilationOptions); + + foreach (var rudeEdit in GetParseOptionsRudeEdits(oldProject.ParseOptions, newProject.ParseOptions)) + { + yield return rudeEdit; + } + + foreach (var rudeEdit in GetCompilationOptionsRudeEdits(oldProject.CompilationOptions, newProject.CompilationOptions)) + { + yield return rudeEdit; + } + + if (oldProject.AssemblyName != newProject.AssemblyName) + { + yield return CreateProjectRudeEdit(ProjectSettingKind.AssemblyName, oldProject.AssemblyName, newProject.AssemblyName); + } + } + #endregion #region Syntax Analysis diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs index 5bbc2faf124..2cf51f34fb9 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/DebuggingSession.cs @@ -12,6 +12,7 @@ using System.Reflection.Metadata; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Contracts.EditAndContinue; using Microsoft.CodeAnalysis.Debugging; using Microsoft.CodeAnalysis.Emit; @@ -331,6 +332,18 @@ internal ImmutableList GetOrCreateEmitBaselines( return []; } + // It is possible to compile a project with assembly references that have + // the same name but different versions, cultures, or public key tokens, + // although the SDK targets prevent such references in practice. + var initiallyReferencedAssemblies = ImmutableDictionary.CreateBuilder>(); + + foreach (var identity in baselineCompilation.ReferencedAssemblyNames) + { + initiallyReferencedAssemblies[identity.Name] = initiallyReferencedAssemblies.TryGetValue(identity.Name, out var value) + ? value.Add(identity) + : OneOrMany.Create(identity); + } + lock (_projectEmitBaselinesGuard) { if (TryGetBaselinesContainingModuleVersion(moduleId, out existingBaselines)) @@ -340,7 +353,7 @@ internal ImmutableList GetOrCreateEmitBaselines( return existingBaselines; } - var newBaseline = new ProjectBaseline(moduleId, baselineProject.Id, initialBaseline, generation: 0); + var newBaseline = new ProjectBaseline(moduleId, baselineProject.Id, initialBaseline, initiallyReferencedAssemblies.ToImmutableDictionary(), generation: 0); var baselines = (existingBaselines ?? []).Add(newBaseline); _projectBaselines[baselineProject.Id] = baselines; diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/DebuggingSessionTelemetry.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/DebuggingSessionTelemetry.cs index 30ea313eb36..6790b42ebf1 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/DebuggingSessionTelemetry.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/DebuggingSessionTelemetry.cs @@ -96,14 +96,18 @@ public static void Log(Data data, Action log, Func map[SessionId] = debugSessionId; map[EditSessionId] = editSessionId; - map["HadCompilationErrors"] = editSessionData.HadCompilationErrors; - map["HadRudeEdits"] = editSessionData.HadRudeEdits; + // Syntax errors + map["HadCompilationErrors"] = editSessionData.HasSyntaxErrors; + + // Blocking rude edits + map["HadRudeEdits"] = editSessionData.HadBlockingRudeEdits; // Changes made to source code during the edit session were valid - they were significant and no rude edits were reported. // The changes still might fail to emit (see EmitDeltaErrorIdCount). map["HadValidChanges"] = editSessionData.HadValidChanges; map["HadValidInsignificantChanges"] = editSessionData.HadValidInsignificantChanges; + // all rude edits (errors and warnings) map["RudeEditsCount"] = editSessionData.RudeEdits.Length; // Number of emit errors. These are any errors only produced during emitting deltas and do not include document analysis errors. @@ -149,7 +153,7 @@ public static void Log(Data data, Action log, Func map["RudeEditKind"] = editKind; map["RudeEditSyntaxKind"] = syntaxKind; - map["RudeEditBlocking"] = editSessionData.HadRudeEdits; + map["RudeEditBlocking"] = editSessionData.HadBlockingRudeEdits; map["RudeEditProjectId"] = ProjectIdToPii(projectId); })); } diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/DocumentAnalysisResults.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/DocumentAnalysisResults.cs index ff62953f3d4..7e834af88f4 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/DocumentAnalysisResults.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/DocumentAnalysisResults.cs @@ -36,7 +36,7 @@ internal sealed class DocumentAnalysisResults public ImmutableArray RudeEdits { get; } /// - /// The first syntax error, or null if the document does not have syntax errors reported by the compiler. + /// The first syntax error, if the document and a syntax error. Null otherwise. /// public Diagnostic? SyntaxError { get; } @@ -90,9 +90,9 @@ internal sealed class DocumentAnalysisResults public TimeSpan ElapsedTime { get; } /// - /// Document contains errors that block EnC analysis. + /// True if the document and contains errors that block EnC analysis. /// - public bool HasSyntaxErrors { get; } + public bool AnalysisBlocked { get; } /// /// Document contains changes. @@ -116,13 +116,13 @@ public DocumentAnalysisResults( EditAndContinueCapabilities requiredCapabilities, TimeSpan elapsedTime, bool hasChanges, - bool hasSyntaxErrors, + bool analysisBlocked, bool hasBlockingRudeEdits) { Debug.Assert(!rudeEdits.IsDefault); Debug.Assert(hasBlockingRudeEdits == (!rudeEdits.IsDefault && rudeEdits.HasBlockingRudeEdits())); - if (hasSyntaxErrors || !hasChanges) + if (analysisBlocked || !hasChanges) { Debug.Assert(activeStatementsOpt.IsDefault); Debug.Assert(semanticEditsOpt.IsDefault); @@ -171,24 +171,18 @@ public DocumentAnalysisResults( LineEdits = lineEditsOpt; RequiredCapabilities = requiredCapabilities; ElapsedTime = elapsedTime; - HasSyntaxErrors = hasSyntaxErrors; + AnalysisBlocked = analysisBlocked; HasChanges = hasChanges; HasBlockingRudeEdits = hasBlockingRudeEdits; } - public bool HasChangesAndErrors - => HasChanges && (HasSyntaxErrors || HasBlockingRudeEdits); - - public bool HasChangesAndSyntaxErrors - => HasChanges && HasSyntaxErrors; - public bool HasSignificantValidChanges => HasChanges && (!SemanticEdits.IsDefaultOrEmpty || !LineEdits.IsDefaultOrEmpty); /// /// Report errors blocking the document analysis. /// - public static DocumentAnalysisResults SyntaxErrors(DocumentId documentId, string filePath, ImmutableArray rudeEdits, Diagnostic? syntaxError, TimeSpan elapsedTime, bool hasChanges) + public static DocumentAnalysisResults Blocked(DocumentId documentId, string filePath, ImmutableArray rudeEdits, Diagnostic? syntaxError, TimeSpan elapsedTime, bool hasChanges) => new( documentId, filePath, @@ -201,7 +195,7 @@ public static DocumentAnalysisResults SyntaxErrors(DocumentId documentId, string EditAndContinueCapabilities.None, elapsedTime, hasChanges, - hasSyntaxErrors: true, + analysisBlocked: true, hasBlockingRudeEdits: !rudeEdits.IsEmpty); /// @@ -220,6 +214,6 @@ public static DocumentAnalysisResults Unchanged(DocumentId documentId, string fi EditAndContinueCapabilities.None, elapsedTime, hasChanges: false, - hasSyntaxErrors: false, + analysisBlocked: false, hasBlockingRudeEdits: false); } diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs index 42ff3017dc2..f78ebea1454 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditAndContinueDiagnosticDescriptors.cs @@ -78,6 +78,16 @@ void AddRudeEdit(RudeEditKind kind, string resourceName, DiagnosticSeverity seve void AddGeneralDiagnostic(EditAndContinueErrorCode code, string resourceName, DiagnosticSeverity severity = DiagnosticSeverity.Error, bool noEffect = false) => Add(GetDescriptorIndex(code), GeneralDiagnosticIdPrefix, (int)code, resourceName, s_encLocString, severity, noEffect); + void AddProjectRudeEdit(ProjectSettingKind kind) + { + var code = EditAndContinueErrorCode.ChangingProjectSettingBase + (int)kind; + var resourceName = nameof(FeaturesResources.Changing_project_setting_0_from_1_to_2_requires_restarting_the_application); + var noEffect = kind.IsWarning(); + var severity = noEffect ? DiagnosticSeverity.Warning : DiagnosticSeverity.Error; + + Add(GetDescriptorIndex(code), GeneralDiagnosticIdPrefix, (int)code, resourceName, s_encLocString, severity, noEffect); + } + // // rude edits // @@ -189,6 +199,20 @@ void AddGeneralDiagnostic(EditAndContinueErrorCode code, string resourceName, Di AddGeneralDiagnostic(EditAndContinueErrorCode.AddingTypeRuntimeCapabilityRequired, nameof(FeaturesResources.ChangesRequiredSynthesizedType)); AddGeneralDiagnostic(EditAndContinueErrorCode.UpdatingDocumentInStaleProject, nameof(FeaturesResources.Changing_source_file_0_in_a_stale_project_has_no_effect_until_the_project_is_rebuit), DiagnosticSeverity.Warning, noEffect: true); + // Project setting rude edits. Defines a distinct error code per setting to simplify telemetry tracking even though some errors share the same message. + + AddGeneralDiagnostic(EditAndContinueErrorCode.ChangingMultiVersionReferences, nameof(FeaturesResources.Project_references_mutliple_assemblies_of_the_same_simple_name_0_1_Changing_a_reference_to_such_an_assembly_requires_restarting_the_application)); + AddGeneralDiagnostic(EditAndContinueErrorCode.ChangingReference, nameof(FeaturesResources.Changing_project_or_package_reference_caused_the_identity_of_referenced_assembly_to_change_from_0_to_1_which_requires_restarting_the_application)); + +#if NET + foreach (var value in Enum.GetValues()) +#else + foreach (ProjectSettingKind value in Enum.GetValues(typeof(ProjectSettingKind))) +#endif + { + AddProjectRudeEdit(value); + } + s_descriptors = builder.ToImmutable(); s_noEffectDiagnosticIds = noEffectDiagnosticIds.ToImmutable(); } @@ -199,6 +223,9 @@ internal static ImmutableArray GetDescriptors() internal static DiagnosticDescriptor GetDescriptor(RudeEditKind kind) => s_descriptors[GetDescriptorIndex(kind)]; + internal static DiagnosticDescriptor GetDescriptor(ProjectSettingKind kind) + => s_descriptors[GetDescriptorIndex(kind)]; + internal static DiagnosticDescriptor GetDescriptor(EditAndContinueErrorCode errorCode) => s_descriptors[GetDescriptorIndex(errorCode)]; @@ -236,6 +263,9 @@ private static string GetDiagnosticId(ManagedHotReloadAvailabilityStatus status) private static int GetDescriptorIndex(RudeEditKind kind) => (int)kind; + private static int GetDescriptorIndex(ProjectSettingKind kind) + => GetDescriptorIndex(EditAndContinueErrorCode.ChangingProjectSettingBase + (int)kind); + private static int GetDescriptorIndex(EditAndContinueErrorCode errorCode) => s_generalDiagnosticBaseIndex + (int)errorCode; diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditAndContinueErrorCode.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditAndContinueErrorCode.cs index 95b7aa239ff..481f46e5bb7 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditAndContinueErrorCode.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditAndContinueErrorCode.cs @@ -14,4 +14,13 @@ internal enum EditAndContinueErrorCode UnableToReadSourceFileOrPdb = 6, AddingTypeRuntimeCapabilityRequired = 7, UpdatingDocumentInStaleProject = 8, + + ChangingMultiVersionReferences = 98, + ChangingReference = 99, + + /// + /// Base code for project setting rude edits. + /// is added to this value. + /// + ChangingProjectSettingBase = 100, } diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditSession.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditSession.cs index e0f2065908a..3d538d5aadb 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditSession.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditSession.cs @@ -11,6 +11,7 @@ using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Contracts.EditAndContinue; using Microsoft.CodeAnalysis.Emit; using Microsoft.CodeAnalysis.ErrorReporting; @@ -154,8 +155,6 @@ public TraceLog Log /// Non-null diagnostic id if the module blocks EnC operation. public async Task ReportModuleDiagnosticsAsync(Guid mvid, Project oldProject, Project newProject, ImmutableArray documentAnalyses, ArrayBuilder diagnostics, CancellationToken cancellationToken) { - Contract.ThrowIfTrue(documentAnalyses.IsEmpty); - var availability = await DebuggingSession.DebuggerService.GetAvailabilityAsync(mvid, cancellationToken).ConfigureAwait(false); if (availability.Status is ManagedHotReloadAvailabilityStatus.ModuleNotLoaded or ManagedHotReloadAvailabilityStatus.Available) { @@ -200,7 +199,7 @@ private static async IAsyncEnumerable CreateChangedLocationsAsync(Proj } // project location: - if (hasRemovedOrAddedDocument) + if (hasRemovedOrAddedDocument || documentAnalyses.IsEmpty) { yield return Location.None; } @@ -291,7 +290,7 @@ public static async ValueTask HasChangesAsync(Solution oldSolution, Soluti } var oldProject = oldSolution.GetProject(newProject.Id); - if (oldProject == null || await HasDocumentDifferencesAsync(oldProject, newProject, documentDifferences: null, cancellationToken).ConfigureAwait(false)) + if (oldProject == null || await HasDifferencesAsync(oldProject, newProject, differences: null, cancellationToken).ConfigureAwait(false)) { // project added or has changes return true; @@ -332,7 +331,7 @@ private static async ValueTask ContentEqualsAsync(TextDocument oldDocument return oldSource.ContentEquals(newSource); } - internal static async ValueTask HasDocumentDifferencesAsync(Project oldProject, Project newProject, ProjectDocumentDifferences? documentDifferences, CancellationToken cancellationToken) + internal static async ValueTask HasDifferencesAsync(Project oldProject, Project newProject, ProjectDifferences? differences, CancellationToken cancellationToken) { if (!newProject.SupportsEditAndContinue()) { @@ -357,12 +356,12 @@ internal static async ValueTask HasDocumentDifferencesAsync(Project oldPro continue; } - if (!documentDifferences.HasValue) + if (differences == null) { return true; } - documentDifferences.Value.ChangedOrAdded.Add(document); + differences.Value.ChangedOrAddedDocuments.Add(document); } foreach (var documentId in newProject.State.DocumentStates.GetAddedStateIds(oldProject.State.DocumentStates)) @@ -373,12 +372,12 @@ internal static async ValueTask HasDocumentDifferencesAsync(Project oldPro continue; } - if (!documentDifferences.HasValue) + if (differences == null) { return true; } - documentDifferences.Value.ChangedOrAdded.Add(document); + differences.Value.ChangedOrAddedDocuments.Add(document); } foreach (var documentId in newProject.State.DocumentStates.GetRemovedStateIds(oldProject.State.DocumentStates)) @@ -389,18 +388,21 @@ internal static async ValueTask HasDocumentDifferencesAsync(Project oldPro continue; } - if (!documentDifferences.HasValue) + if (differences == null) { return true; } - documentDifferences.Value.Deleted.Add(document); + differences.Value.DeletedDocuments.Add(document); } - // Any changes in non-generated document content might affect source generated documents as well, - // no need to check further in that case. + // The following will check for any changes in non-generated document content (editorconfig, additional docs). + // If we already have changes and we are collecting document differences, we don't need to check for these as + // tey do not contribute directly to changed documents. They may trigger changes in source-generated documents though, so + // if we are not collecting differences and no changes have been observed so far (if they were we would have returned above), + // we need to check for changes in editorconfig and additional documents. - if (documentDifferences?.Any() == true) + if (differences?.Any() == true) { return true; } @@ -434,11 +436,11 @@ internal static async ValueTask HasDocumentDifferencesAsync(Project oldPro return false; } - internal static async Task GetDocumentDifferencesAsync(TraceLog log, Project oldProject, Project newProject, ProjectDocumentDifferences documentDifferences, ArrayBuilder diagnostics, CancellationToken cancellationToken) + internal static async Task GetProjectDifferencesAsync(TraceLog log, Project oldProject, Project newProject, ProjectDifferences documentDifferences, ArrayBuilder diagnostics, CancellationToken cancellationToken) { documentDifferences.Clear(); - if (!await HasDocumentDifferencesAsync(oldProject, newProject, documentDifferences, cancellationToken).ConfigureAwait(false)) + if (!await HasDifferencesAsync(oldProject, newProject, documentDifferences, cancellationToken).ConfigureAwait(false)) { return; } @@ -457,7 +459,7 @@ internal static async Task GetDocumentDifferencesAsync(TraceLog log, Project old continue; } - documentDifferences.ChangedOrAdded.Add(newProject.GetOrCreateSourceGeneratedDocument(newState)); + documentDifferences.ChangedOrAddedDocuments.Add(newProject.GetOrCreateSourceGeneratedDocument(newState)); } foreach (var documentId in newSourceGeneratedDocumentStates.GetAddedStateIds(oldSourceGeneratedDocumentStates)) @@ -468,7 +470,7 @@ internal static async Task GetDocumentDifferencesAsync(TraceLog log, Project old continue; } - documentDifferences.ChangedOrAdded.Add(newProject.GetOrCreateSourceGeneratedDocument(newState)); + documentDifferences.ChangedOrAddedDocuments.Add(newProject.GetOrCreateSourceGeneratedDocument(newState)); } foreach (var documentId in newSourceGeneratedDocumentStates.GetRemovedStateIds(oldSourceGeneratedDocumentStates)) @@ -479,7 +481,7 @@ internal static async Task GetDocumentDifferencesAsync(TraceLog log, Project old continue; } - documentDifferences.Deleted.Add(oldProject.GetOrCreateSourceGeneratedDocument(oldState)); + documentDifferences.DeletedDocuments.Add(oldProject.GetOrCreateSourceGeneratedDocument(oldState)); } } @@ -545,9 +547,9 @@ internal static async IAsyncEnumerable GetChangedDocumentsAsync(Trac } } - private async Task<(ImmutableArray results, bool hasOutOfSyncDocument)> AnalyzeDocumentsAsync( + private async Task<(ImmutableArray results, bool hasOutOfSyncDocument)> AnalyzeProjectDifferencesAsync( Solution newSolution, - ProjectDocumentDifferences documentDifferences, + ProjectDifferences differences, ActiveStatementSpanProvider newDocumentActiveStatementSpanProvider, ArrayBuilder diagnostics, CancellationToken cancellationToken) @@ -555,7 +557,7 @@ internal static async IAsyncEnumerable GetChangedDocumentsAsync(Trac using var _ = ArrayBuilder<(Document? oldDocument, Document? newDocument)>.GetInstance(out var documents); var hasOutOfSyncDocument = false; - foreach (var newDocument in documentDifferences.ChangedOrAdded) + foreach (var newDocument in differences.ChangedOrAddedDocuments) { var (oldDocument, oldDocumentState) = await DebuggingSession.LastCommittedSolution.GetDocumentAndStateAsync(newDocument, cancellationToken, reloadOutOfSyncDocument: true).ConfigureAwait(false); switch (oldDocumentState) @@ -587,7 +589,7 @@ internal static async IAsyncEnumerable GetChangedDocumentsAsync(Trac } } - foreach (var oldDocument in documentDifferences.Deleted) + foreach (var oldDocument in differences.DeletedDocuments) { documents.Add((oldDocument, newDocument: null)); } @@ -614,15 +616,9 @@ private static ProjectAnalysisSummary GetProjectAnalysisSummary(ImmutableArray diagnostics) + { + Contract.ThrowIfFalse(oldProject.Language == newProject.Language); + + var analyzer = newProject.GetRequiredLanguageService(); + + var hasBlockingRudeEdit = false; + + foreach (var diagnostic in analyzer.GetProjectSettingRudeEdits(oldProject, newProject)) + { + hasBlockingRudeEdit |= diagnostic.Severity == DiagnosticSeverity.Error; + diagnostics.Add(diagnostic); + } + + return hasBlockingRudeEdit; + } + + private static bool HasReferenceRudeEdits(ImmutableDictionary> oldReferencedAssemblies, Compilation newCompilation, ArrayBuilder projectDiagnostics) + { + var hasRudeEdit = false; + + foreach (var newReference in newCompilation.ReferencedAssemblyNames) + { + if (oldReferencedAssemblies.TryGetValue(newReference.Name, out var oldReferences)) + { + if (oldReferences.Contains(newReference)) + { + // found exact match + continue; + } + + hasRudeEdit = true; + + if (oldReferences.Count > 1) + { + // For simplicity we disallow changing references to assembly references that don't have unique simple name. + // This case should be very rare in practice. + + projectDiagnostics.Add(Diagnostic.Create( + EditAndContinueDiagnosticDescriptors.GetDescriptor(EditAndContinueErrorCode.ChangingMultiVersionReferences), + Location.None, + [newReference.Name, string.Join(", ", oldReferences.ToImmutable().Select(static r => $"'{r}'"))])); + + break; + } + + // Reference identity changed. + + projectDiagnostics.Add(Diagnostic.Create( + EditAndContinueDiagnosticDescriptors.GetDescriptor(EditAndContinueErrorCode.ChangingReference), + Location.None, + [oldReferences[0].ToString(), newReference.ToString()])); + } + } + + return hasRudeEdit; + } + internal static async ValueTask GetProjectChangesAsync( ActiveStatementsMap baseActiveStatements, Compilation oldCompilation, @@ -668,9 +722,6 @@ internal static async ValueTask GetProjectChangesAsync( continue; } - // we shouldn't be asking for deltas in presence of errors: - Contract.ThrowIfTrue(analysis.HasChangesAndErrors); - // Active statements are calculated if document changed and has no syntax errors: Contract.ThrowIfTrue(analysis.ActiveStatements.IsDefault); @@ -851,14 +902,14 @@ public async ValueTask EmitSolutionUpdateAsync( using var _3 = ArrayBuilder.GetInstance(out var newProjectBaselines); using var _4 = ArrayBuilder.GetInstance(out var projectsToStale); using var _5 = PooledDictionary>.GetInstance(out var diagnosticBuilders); - using var documentDifferences = new ProjectDocumentDifferences(); + using var projectDifferences = new ProjectDifferences(); // After all projects have been analyzed "true" value indicates changed document that is only included in stale projects. var changedDocumentsStaleness = new Dictionary(SolutionState.FilePathComparer); void UpdateChangedDocumentsStaleness(bool isStale) { - foreach (var changedDocument in documentDifferences.ChangedOrAdded) + foreach (var changedDocument in projectDifferences.ChangedOrAddedDocuments) { var path = changedDocument.FilePath; @@ -877,6 +928,7 @@ void UpdateChangedDocumentsStaleness(bool isStale) } Diagnostic? syntaxError = null; + ProjectAnalysisSummary? projectSummaryToReport = null; var oldSolution = DebuggingSession.LastCommittedSolution; @@ -909,15 +961,22 @@ void UpdateChangedDocumentsStaleness(bool isStale) continue; } - projectDiagnostics = ArrayBuilder.GetInstance(); + Debug.Assert(oldProject.SupportsEditAndContinue()); - await GetDocumentDifferencesAsync(Log, oldProject, newProject, documentDifferences, projectDiagnostics, cancellationToken).ConfigureAwait(false); - if (documentDifferences.IsEmpty) + if (!oldProject.ProjectSettingsSupportEditAndContinue(Log)) { + // reason alrady reported continue; } - Log.Write($"Found {documentDifferences.ChangedOrAdded.Count} potentially changed and {documentDifferences.Deleted.Count} deleted document(s) in project {newProject.GetLogDisplay()}"); + projectDiagnostics = ArrayBuilder.GetInstance(); + + await GetProjectDifferencesAsync(Log, oldProject, newProject, projectDifferences, projectDiagnostics, cancellationToken).ConfigureAwait(false); + + if (projectDifferences.HasDocumentChanges) + { + Log.Write($"Found {projectDifferences.ChangedOrAddedDocuments.Count} potentially changed, {projectDifferences.DeletedDocuments.Count} deleted document(s) in project {newProject.GetLogDisplay()}"); + } var isStaleProject = oldSolution.IsStaleProject(newProject.Id); @@ -936,8 +995,7 @@ void UpdateChangedDocumentsStaleness(bool isStale) // The MVID is required for emit so we consider the error permanent and report it here. // Bail before analyzing documents as the analysis needs to read the PDB which will likely fail if we can't even read the MVID. projectDiagnostics.Add(mvidReadError); - - Telemetry.LogProjectAnalysisSummary(ProjectAnalysisSummary.ValidChanges, newProject.State.ProjectInfo.Attributes.TelemetryId, projectDiagnostics); + projectSummaryToReport = ProjectAnalysisSummary.ValidChanges; continue; } @@ -964,7 +1022,7 @@ void UpdateChangedDocumentsStaleness(bool isStale) // instead of the true C.M(string). var (changedDocumentAnalyses, hasOutOfSyncChangedDocument) = - await AnalyzeDocumentsAsync(solution, documentDifferences, solutionActiveStatementSpanProvider, projectDiagnostics, cancellationToken).ConfigureAwait(false); + await AnalyzeProjectDifferencesAsync(solution, projectDifferences, solutionActiveStatementSpanProvider, projectDiagnostics, cancellationToken).ConfigureAwait(false); if (hasOutOfSyncChangedDocument) { @@ -999,9 +1057,22 @@ void UpdateChangedDocumentsStaleness(bool isStale) } var projectSummary = GetProjectAnalysisSummary(changedDocumentAnalyses); + + if (HasProjectSettingsBlockingRudeEdits(oldProject, newProject, projectDiagnostics)) + { + // If the project settings have changed and the change is a rude edit, + // block applying the changes even if there no other changes to the project documents. + // This is to avoid advancing the solution snapshot to an inconsistent state. + projectSummary = ProjectAnalysisSummary.InvalidChanges; + } + + projectSummaryToReport = projectSummary; Log.Write($"Project summary for {newProject.GetLogDisplay()}: {projectSummary}"); - if (projectSummary is ProjectAnalysisSummary.NoChanges or ProjectAnalysisSummary.ValidInsignificantChanges) + // Unsupported changes in referenced assemblies will be reported below. + if (projectSummary is ProjectAnalysisSummary.NoChanges or ProjectAnalysisSummary.ValidInsignificantChanges && + oldProject.MetadataReferences.SequenceEqual(newProject.MetadataReferences) && + oldProject.ProjectReferences.SequenceEqual(newProject.ProjectReferences)) { continue; } @@ -1028,34 +1099,47 @@ void UpdateChangedDocumentsStaleness(bool isStale) } } - if (moduleBlockingDiagnosticId != null || projectSummary != ProjectAnalysisSummary.ValidChanges) + if (projectSummary == ProjectAnalysisSummary.InvalidChanges) { - Telemetry.LogProjectAnalysisSummary(projectSummary, newProject.State.ProjectInfo.Attributes.TelemetryId, projectDiagnostics); - + // Write document changes to log directory so that we can inspect them for rude edits: await LogDocumentChangesAsync(generation: null, cancellationToken).ConfigureAwait(false); continue; } + if (moduleBlockingDiagnosticId != null) + { + continue; + } + var oldCompilation = await oldProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false); Contract.ThrowIfNull(oldCompilation); + // Report diagnosics even when the module is never going to be loaded (e.g. in multi-targeting scenario, where only one framework being debugged). + // This is consistent with reporting compilation errors - the IDE reports them for all TFMs regardless of what framework the app is running on. var projectBaselines = DebuggingSession.GetOrCreateEmitBaselines(mvid, oldProject, oldCompilation, projectDiagnostics, out var baselineAccessLock); if (projectBaselines.IsEmpty) { - // Report diagnosics even when the module is never going to be loaded (e.g. in multi-targeting scenario, where only one framework being debugged). - // This is consistent with reporting compilation errors - the IDE reports them for all TFMs regardless of what framework the app is running on. - Telemetry.LogProjectAnalysisSummary(projectSummary, newProject.State.ProjectInfo.Attributes.TelemetryId, projectDiagnostics); + continue; + } - await LogDocumentChangesAsync(generation: null, cancellationToken).ConfigureAwait(false); + var newCompilation = await newProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + Contract.ThrowIfNull(newCompilation); + + // Compare referenced assemblies against the baseline. The runtime does not provide means to replace already loaded assemblies + // and therefore the versions of referenced assemblies in the new compilation can't change from the baseline. + if (projectBaselines.Any(baseline => HasReferenceRudeEdits(baseline.InitiallyReferencedAssemblies, newCompilation, projectDiagnostics))) + { continue; } - Log.Write($"Emitting update of {newProject.GetLogDisplay()}"); + if (projectSummary is ProjectAnalysisSummary.NoChanges or ProjectAnalysisSummary.ValidInsignificantChanges) + { + continue; + } - var newCompilation = await newProject.GetCompilationAsync(cancellationToken).ConfigureAwait(false); + Log.Write($"Emitting update of {newProject.GetLogDisplay()}"); - // project must support compilations since it supports EnC - Contract.ThrowIfNull(newCompilation); + await LogDocumentChangesAsync(projectBaselines.First().Generation + 1, cancellationToken).ConfigureAwait(false); var oldActiveStatementsMap = await BaseActiveStatements.GetValueAsync(cancellationToken).ConfigureAwait(false); var projectChanges = await GetProjectChangesAsync(oldActiveStatementsMap, oldCompilation, newCompilation, oldProject, newProject, changedDocumentAnalyses, cancellationToken).ConfigureAwait(false); @@ -1076,8 +1160,6 @@ void UpdateChangedDocumentsStaleness(bool isStale) foreach (var projectBaseline in projectBaselines) { - await LogDocumentChangesAsync(projectBaseline.Generation + 1, cancellationToken).ConfigureAwait(false); - using var pdbStream = SerializableBytes.CreateWritableStream(); using var metadataStream = SerializableBytes.CreateWritableStream(); using var ilStream = SerializableBytes.CreateWritableStream(); @@ -1168,7 +1250,7 @@ void UpdateChangedDocumentsStaleness(bool isStale) deltas.Add(delta); nonRemappableRegions.Add((mvid, moduleNonRemappableRegions)); - newProjectBaselines.Add(new ProjectBaseline(mvid, projectBaseline.ProjectId, emitResult.Baseline, projectBaseline.Generation + 1)); + newProjectBaselines.Add(new ProjectBaseline(mvid, projectBaseline.ProjectId, emitResult.Baseline, projectBaseline.InitiallyReferencedAssemblies, projectBaseline.Generation + 1)); var fileLog = Log.FileLog; if (fileLog != null) @@ -1177,8 +1259,6 @@ void UpdateChangedDocumentsStaleness(bool isStale) } } - Telemetry.LogProjectAnalysisSummary(projectSummary, newProject.State.ProjectInfo.Attributes.TelemetryId, projectDiagnostics); - async ValueTask LogDocumentChangesAsync(int? generation, CancellationToken cancellationToken) { var fileLog = Log.FileLog; @@ -1198,6 +1278,11 @@ async ValueTask LogDocumentChangesAsync(int? generation, CancellationToken cance } finally { + if (projectSummaryToReport.HasValue) + { + Telemetry.LogProjectAnalysisSummary(projectSummaryToReport.Value, newProject.State.ProjectInfo.Attributes.TelemetryId, projectDiagnostics); + } + if (!projectDiagnostics.IsEmpty) { diagnosticBuilders.Add(newProject.Id, projectDiagnostics); @@ -1226,11 +1311,19 @@ async ValueTask LogDocumentChangesAsync(int? generation, CancellationToken cance Telemetry.LogRuntimeCapabilities(await Capabilities.GetValueAsync(cancellationToken).ConfigureAwait(false)); + if (syntaxError != null) + { + Telemetry.LogSyntaxError(); + } + if (hasPersistentErrors) { return SolutionUpdate.Empty(diagnostics, syntaxError, ModuleUpdateStatus.Blocked); } + // syntax error is a persistent error + Contract.ThrowIfTrue(syntaxError != null); + var updates = deltas.ToImmutable(); EmitSolutionUpdateResults.GetProjectsToRebuildAndRestart( @@ -1249,7 +1342,7 @@ async ValueTask LogDocumentChangesAsync(int? generation, CancellationToken cance nonRemappableRegions.ToImmutable(), newProjectBaselines.ToImmutable(), diagnostics, - syntaxError, + syntaxError: null, projectsToRestart, projectsToRebuild); } diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditSessionTelemetry.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditSessionTelemetry.cs index ac882f11e94..a64fa9a6235 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditSessionTelemetry.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/EditSessionTelemetry.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; +using Microsoft.CodeAnalysis.Collections; namespace Microsoft.CodeAnalysis.EditAndContinue; @@ -19,8 +20,8 @@ internal readonly struct Data(EditSessionTelemetry telemetry) public readonly ImmutableArray ProjectsWithValidDelta = telemetry._projectsWithValidDelta.AsImmutable(); public readonly ImmutableArray ProjectsWithUpdatedBaselines = telemetry._projectsWithUpdatedBaselines.AsImmutable(); public readonly EditAndContinueCapabilities Capabilities = telemetry._capabilities; - public readonly bool HadCompilationErrors = telemetry._hadCompilationErrors; - public readonly bool HadRudeEdits = telemetry._hadRudeEdits; + public readonly bool HasSyntaxErrors = telemetry._hadSyntaxErrors; + public readonly bool HadBlockingRudeEdits = telemetry._hadBlockingRudeEdits; public readonly bool HadValidChanges = telemetry._hadValidChanges; public readonly bool HadValidInsignificantChanges = telemetry._hadValidInsignificantChanges; public readonly bool InBreakState = telemetry._inBreakState!.Value; @@ -40,8 +41,8 @@ internal readonly struct Data(EditSessionTelemetry telemetry) private readonly HashSet _projectsWithValidDelta = []; private readonly HashSet _projectsWithUpdatedBaselines = []; - private bool _hadCompilationErrors; - private bool _hadRudeEdits; + private bool _hadSyntaxErrors; + private bool _hadBlockingRudeEdits; private bool _hadValidChanges; private bool _hadValidInsignificantChanges; private bool? _inBreakState; @@ -60,8 +61,8 @@ public Data GetDataAndClear() _emitErrorIds.Clear(); _projectsWithValidDelta.Clear(); _projectsWithUpdatedBaselines.Clear(); - _hadCompilationErrors = false; - _hadRudeEdits = false; + _hadSyntaxErrors = false; + _hadBlockingRudeEdits = false; _hadValidChanges = false; _hadValidInsignificantChanges = false; _inBreakState = null; @@ -72,7 +73,7 @@ public Data GetDataAndClear() } } - public bool IsEmpty => !(_hadCompilationErrors || _hadRudeEdits || _hadValidChanges || _hadValidInsignificantChanges); + public bool IsEmpty => !(_hadSyntaxErrors || _hadBlockingRudeEdits || _hadValidChanges || _hadValidInsignificantChanges); public void SetBreakState(bool value) => _inBreakState = value; @@ -83,6 +84,9 @@ public void LogEmitDifferenceTime(TimeSpan span) public void LogAnalysisTime(TimeSpan span) => _analysisTime += span; + public void LogSyntaxError() + => _hadSyntaxErrors = true; + public void LogProjectAnalysisSummary(ProjectAnalysisSummary summary, Guid projectTelemetryId, IEnumerable diagnostics) { lock (_guard) @@ -90,10 +94,17 @@ public void LogProjectAnalysisSummary(ProjectAnalysisSummary summary, Guid proje var hasError = false; foreach (var diagnostic in diagnostics) { - if (diagnostic.Severity == DiagnosticSeverity.Error && !diagnostic.IsRudeEdit()) + if (diagnostic.Severity == DiagnosticSeverity.Error) { - _emitErrorIds.Add(diagnostic.Id); - hasError = true; + if (diagnostic.IsRudeEdit()) + { + _hadBlockingRudeEdits = true; + } + else + { + _emitErrorIds.Add(diagnostic.Id); + hasError = true; + } } } @@ -102,12 +113,7 @@ public void LogProjectAnalysisSummary(ProjectAnalysisSummary summary, Guid proje case ProjectAnalysisSummary.NoChanges: break; - case ProjectAnalysisSummary.SyntaxErrors: - _hadCompilationErrors = true; - break; - - case ProjectAnalysisSummary.RudeEdits: - _hadRudeEdits = true; + case ProjectAnalysisSummary.InvalidChanges: break; case ProjectAnalysisSummary.ValidChanges: diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/IEditAndContinueAnalyzer.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/IEditAndContinueAnalyzer.cs index 5a587d5975f..45cd58b5c57 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/IEditAndContinueAnalyzer.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/IEditAndContinueAnalyzer.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; +using System.Collections.Generic; using System.Collections.Immutable; using System.Threading; using System.Threading.Tasks; @@ -24,4 +26,6 @@ Task AnalyzeDocumentAsync( CancellationToken cancellationToken); ActiveStatementExceptionRegions GetExceptionRegions(SyntaxNode syntaxRoot, TextSpan unmappedActiveStatementSpan, bool isNonLeaf, CancellationToken cancellationToken); + + IEnumerable GetProjectSettingRudeEdits(Project oldProject, Project newProject); } diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectAnalysisSummary.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectAnalysisSummary.cs index 8f03cc087b8..663db12a780 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectAnalysisSummary.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectAnalysisSummary.cs @@ -12,14 +12,9 @@ internal enum ProjectAnalysisSummary NoChanges, /// - /// Project contains syntax errors that block EnC analysis. + /// Project contains rude edits or a document whose analysis is blocked due to syntax error or rude edit in parse options. /// - SyntaxErrors, - - /// - /// Project contains rude edits. - /// - RudeEdits, + InvalidChanges, /// /// The project only changed in comments, whitespaces, etc. that don't require compilation. diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectBaseline.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectBaseline.cs index 8b80110e4f2..5b75ecf61ac 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectBaseline.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectBaseline.cs @@ -3,14 +3,17 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis.Collections; using Microsoft.CodeAnalysis.Emit; namespace Microsoft.CodeAnalysis.EditAndContinue; -internal sealed class ProjectBaseline(Guid moduleId, ProjectId projectId, EmitBaseline emitBaseline, int generation) +internal sealed class ProjectBaseline(Guid moduleId, ProjectId projectId, EmitBaseline emitBaseline, ImmutableDictionary> initiallyReferencedAssemblies, int generation) { public Guid ModuleId { get; } = moduleId; public ProjectId ProjectId { get; } = projectId; public EmitBaseline EmitBaseline { get; } = emitBaseline; + public ImmutableDictionary> InitiallyReferencedAssemblies { get; } = initiallyReferencedAssemblies; public int Generation { get; } = generation; } diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectDifferences.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectDifferences.cs new file mode 100644 index 00000000000..aaad8f29664 --- /dev/null +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectDifferences.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; +using Microsoft.CodeAnalysis.PooledObjects; + +namespace Microsoft.CodeAnalysis.EditAndContinue; + +/// +/// Differences between documents of old and new projects. +/// +internal readonly struct ProjectDifferences() : IDisposable +{ + public readonly ArrayBuilder ChangedOrAddedDocuments = ArrayBuilder.GetInstance(); + public readonly ArrayBuilder DeletedDocuments = ArrayBuilder.GetInstance(); + + public void Dispose() + { + ChangedOrAddedDocuments.Free(); + DeletedDocuments.Free(); + } + + public bool HasDocumentChanges + => !ChangedOrAddedDocuments.IsEmpty || !DeletedDocuments.IsEmpty; + + public bool Any() + => HasDocumentChanges; + + public bool IsEmpty + => !Any(); + + public void Clear() + { + ChangedOrAddedDocuments.Clear(); + DeletedDocuments.Clear(); + } +} diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectDocumentDifferences.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectDocumentDifferences.cs deleted file mode 100644 index 9b39626ffd0..00000000000 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectDocumentDifferences.cs +++ /dev/null @@ -1,35 +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 Microsoft.CodeAnalysis.PooledObjects; - -namespace Microsoft.CodeAnalysis.EditAndContinue; - -/// -/// Differences between documents of old and new projects. -/// -internal readonly struct ProjectDocumentDifferences() : IDisposable -{ - public readonly ArrayBuilder ChangedOrAdded = ArrayBuilder.GetInstance(); - public readonly ArrayBuilder Deleted = ArrayBuilder.GetInstance(); - - public void Dispose() - { - ChangedOrAdded.Free(); - Deleted.Free(); - } - - public bool IsEmpty - => ChangedOrAdded.IsEmpty && Deleted.IsEmpty; - - public bool Any() - => !IsEmpty; - - public void Clear() - { - ChangedOrAdded.Clear(); - Deleted.Clear(); - } -} diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectSettingKind.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectSettingKind.cs new file mode 100644 index 00000000000..9ea9ec6c60b --- /dev/null +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/ProjectSettingKind.cs @@ -0,0 +1,99 @@ +// Licensed to the .NET Foundation under one or more 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 Microsoft.CodeAnalysis.EditAndContinue; + +/// +/// Represents project properties and items that impact parse options, compilation options and source file context interpretation. +/// +/// Project settings fall into following categories: +/// 1) Change requires restart. Error is reported. +/// E.g. language version +/// +/// 2) Change has no-effect until restart. Warning is reported if tracked by . +/// E.g. output type, platform, emit options +/// Not all project settings are tracked by Roslyn. Only those that are are reported. +/// If we want to enable auto-restart when a setting is changed we need to track it in . +/// +/// 5) Change has no effect on emitted IL/metadata, the effect is not observable to the application. Not reported. +/// E.g. analyzer settings, allow unsafe, nullable, code page, delay sign, no warn, xml doc file, embedded sources, etc. +/// +/// The enum only includes settings from categories [1] and [2]. +/// The names of the enum members should match the corresponding msbuild property names. +/// +internal enum ProjectSettingKind +{ + /// + /// Error to avoid confusion and inconsistencies. + /// If changed we would interpret changed syntax trees using one language version while unchanged would use another language version. + /// We would also compile changed members using one version while unchanged would use another. + /// + LangVersion = 0, + + /// + /// Error for the same reasons as . + /// + Features = 1, + + /// + /// Error for the same reasons as . + /// + DefineConstants = 2, + + /// + /// Error for the same reasons as . + /// + CheckForOverflowUnderflow = 3, + + /// + /// Warning since output type only affects entry point. + /// + OutputType = 4, + + /// + /// Warning. + /// + StartupObject = 5, + + /// + /// Error, need to preserve the module name. + /// + ModuleAssemblyName = 9, + + /// + /// Error, need to preserve the assembly name. + /// + AssemblyName = 10, + + /// + /// Warning, can't be changed without restarting the application but not blocking. + /// + Platform = 11, + + /// + /// Must be . + /// + OptimizationLevel = 12, + + // VB specific settings + + /// + /// Error. Can't change namespace of existing types. + /// + RootNamespace = 50, + + OptionStrict = 51, + OptionInfer = 52, + OptionExplicit = 53, + OptionCompare = 54, +} + +internal static class ProjectSettingKindExtensions +{ + public static bool IsWarning(this ProjectSettingKind kind) + => kind is + ProjectSettingKind.OutputType or + ProjectSettingKind.StartupObject or + ProjectSettingKind.Platform; +} diff --git a/src/roslyn/src/Features/Core/Portable/EditAndContinue/Utilities/Extensions.cs b/src/roslyn/src/Features/Core/Portable/EditAndContinue/Utilities/Extensions.cs index e0eb40acb4b..2b8fb6b2627 100644 --- a/src/roslyn/src/Features/Core/Portable/EditAndContinue/Utilities/Extensions.cs +++ b/src/roslyn/src/Features/Core/Portable/EditAndContinue/Utilities/Extensions.cs @@ -72,6 +72,26 @@ void LogReason(string message) return true; } + /// + /// True if project settings are compatible with Edit and Continue. + /// + public static bool ProjectSettingsSupportEditAndContinue(this Project project, TraceLog? log = null) + { + Contract.ThrowIfFalse(project.SupportsEditAndContinue()); + Contract.ThrowIfNull(project.CompilationOptions); + + if (project.CompilationOptions.OptimizationLevel != OptimizationLevel.Debug) + { + LogReason(nameof(ProjectSettingKind.OptimizationLevel), project.CompilationOptions.OptimizationLevel.ToString()); + return false; + } + + void LogReason(string settingName, string value) + => log?.Write($"Project '{project.GetLogDisplay()}' setting '{settingName}' value '{value}' is not compatible with EnC"); + + return true; + } + public static string GetLogDisplay(this Project project) => project.FilePath != null ? $"'{project.FilePath}'" + (project.State.NameAndFlavor.flavor is { } flavor ? $" ('{flavor}')" : "") diff --git a/src/roslyn/src/Features/Core/Portable/FeaturesResources.resx b/src/roslyn/src/Features/Core/Portable/FeaturesResources.resx index 139d6ea4d40..726a5036b07 100644 --- a/src/roslyn/src/Features/Core/Portable/FeaturesResources.resx +++ b/src/roslyn/src/Features/Core/Portable/FeaturesResources.resx @@ -369,6 +369,18 @@ Adding or moving {0} of a COM interface requires restarting the application. + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + + default> + Updating the modifiers of {0} requires restarting the application. diff --git a/src/roslyn/src/Features/Core/Portable/ImplementInterface/ImplementInterfaceCodeRefactoringProvider.cs b/src/roslyn/src/Features/Core/Portable/ImplementInterface/ImplementInterfaceCodeRefactoringProvider.cs new file mode 100644 index 00000000000..c75c4a473a4 --- /dev/null +++ b/src/roslyn/src/Features/Core/Portable/ImplementInterface/ImplementInterfaceCodeRefactoringProvider.cs @@ -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. + +using System; +using System.Composition; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeRefactorings; +using Microsoft.CodeAnalysis.Collections; +using Microsoft.CodeAnalysis.Host.Mef; +using Microsoft.CodeAnalysis.Shared.Extensions; + +namespace Microsoft.CodeAnalysis.ImplementInterface; + +[ExportCodeRefactoringProvider(LanguageNames.CSharp, LanguageNames.VisualBasic, + Name = PredefinedCodeRefactoringProviderNames.ImplementInterface), Shared] +[method: ImportingConstructor] +[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] +internal sealed class ImplementInterfaceCodeRefactoringProvider() : CodeRefactoringProvider +{ + public override async Task ComputeRefactoringsAsync(CodeRefactoringContext context) + { + var (document, textSpan, cancellationToken) = context; + + var helpers = document.GetRequiredLanguageService(); + var sourceText = await document.GetValueTextAsync(cancellationToken).ConfigureAwait(false); + var root = await document.GetRequiredSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + + // We offer the refactoring when the user is between any members of a class/struct and are on a blank line. + if (!helpers.IsBetweenTypeMembers(sourceText, root, textSpan.Start, out var typeDeclaration)) + return; + + var service = document.GetRequiredLanguageService(); + using var allCodeActions = TemporaryArray.Empty; + + foreach (var typeNode in service.GetInterfaceTypes(typeDeclaration)) + { + var codeActions = await service.GetCodeActionsAsync( + document, typeNode, cancellationToken).ConfigureAwait(false); + + allCodeActions.AddRange(codeActions); + } + + context.RegisterRefactorings(allCodeActions.ToImmutableAndClear(), textSpan); + } +} diff --git a/src/roslyn/src/Features/Core/Portable/SemanticSearch/ISemanticSearchCopilotService.cs b/src/roslyn/src/Features/Core/Portable/SemanticSearch/ISemanticSearchCopilotService.cs deleted file mode 100644 index 895018ce8d4..00000000000 --- a/src/roslyn/src/Features/Core/Portable/SemanticSearch/ISemanticSearchCopilotService.cs +++ /dev/null @@ -1,18 +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 Microsoft.CodeAnalysis.SemanticSearch; - -internal interface ISemanticSearchCopilotService -{ - bool IsAvailable { get; } - - /// - /// Translates natural language to C# query. - /// - ValueTask TryGetQueryAsync(string text, SemanticSearchCopilotContext context, CancellationToken cancellationToken); -} diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf index f03c674e673..631eacc18ba 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf @@ -450,6 +450,16 @@ Ujistěte se, že specifikátor tt použijete pro jazyky, pro které je nezbytn Změna typů parametrů u {0} vyžaduje restartování aplikace. + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application Změna pseudovlastního atributu {0} u {1} vyžaduje restartování aplikace. @@ -1350,6 +1360,11 @@ Ujistěte se, že specifikátor tt použijete pro jazyky, pro které je nezbytn Zjistil se pravděpodobný řetězec JSON + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array Vlastnosti nejsou v poli povolené @@ -3628,6 +3643,11 @@ Pokud se specifikátor formátu d použije bez dalších specifikátorů vlastn Specifikátor vlastního formátu dddd (a libovolný počet dalších specifikátorů d) reprezentuje celý název dne v týdnu. Lokalizovaný název dne v týdnu se načítá z vlastnosti DateTimeFormatInfo.DayNames aktuální nebo zadané jazykové verze. + + default> + default> + + discard proměnná typu discard diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf index 20c77de3dee..3f9bae573d5 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf @@ -450,6 +450,16 @@ Stellen Sie sicher, dass Sie den Bezeichner "tt" für Sprachen verwenden, für d Das Ändern von Parametertypen von {0} erfordert einen Neustart der Anwendung. + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application Das Ändern des pseudobenutzerdefinierten Attributs „{0}“ von {1} erfordert einen Neustart der Anwendung. @@ -1350,6 +1360,11 @@ Stellen Sie sicher, dass Sie den Bezeichner "tt" für Sprachen verwenden, für d Wahrscheinliche JSON-Zeichenfolge erkannt + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array Nicht zulässige Eigenschaften in einem Array @@ -3628,6 +3643,11 @@ Bei Verwendung des Formatbezeichners "d" ohne weitere benutzerdefinierte Formatb Der benutzerdefinierte Formatbezeichner "dddd" (plus beliebig viele zusätzliche d-Bezeichner) repräsentiert den vollständigen Namen des Wochentags. Der lokalisierte Name des Wochentags wird aus der DateTimeFormatInfo.DayNames-Eigenschaft der aktuellen oder angegebenen Kultur abgerufen. + + default> + default> + + discard Ausschussvariable diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf index f09a4f93961..e934912a85f 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf @@ -450,6 +450,16 @@ Asegúrese de usar el especificador "tt" para los idiomas para los que es necesa Para cambiar los tipos de parámetros de {0}se requiere reiniciar la aplicación. + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application Para cambiar el atributo pseudo-personalizado "{0}" de {1} se requiere reiniciar la aplicación @@ -1350,6 +1360,11 @@ Asegúrese de usar el especificador "tt" para los idiomas para los que es necesa Cadena JSON probable detectada + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array Propiedades no permitidas en una matriz @@ -3628,6 +3643,11 @@ Si el especificador de formato "d" se usa sin otros especificadores de formato p El especificador de formato personalizado "dddd" (más cualquier número de especificadores "d" adicionales) representa el nombre completo del día de la semana. El nombre localizado del día de la semana se recupera de la propiedad DateTimeFormatInfo.DayNames de la referencia cultural actual o especificada. + + default> + default> + + discard descartar diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf index cb28a6e18d4..222317bf738 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf @@ -450,6 +450,16 @@ Veillez à utiliser le spécificateur "tt" pour les langues où il est nécessai La modification des types de paramètres de {0} requiert le redémarrage de l’application. + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application La modification de l’attribut pseudo-personnalisé « {0} » de {1} requiert le redémarrage de l’application @@ -1350,6 +1360,11 @@ Veillez à utiliser le spécificateur "tt" pour les langues où il est nécessai Chaîne JSON probable détectée + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array Propriétés non autorisées dans un tableau @@ -3628,6 +3643,11 @@ Si le spécificateur de format "d" est utilisé sans autres spécificateurs de f Le spécificateur de format personnalisé "dddd" (plus n'importe quel nombre de spécificateurs "d" supplémentaires) représente le nom complet du jour de la semaine. Le nom localisé du jour de la semaine est récupéré à partir de la propriété DateTimeFormatInfo.DayNames de la culture actuelle ou spécifiée. + + default> + default> + + discard discard diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf index 35c70870dc3..2045461386a 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf @@ -450,6 +450,16 @@ Assicurarsi di usare l'identificatore "tt" per le lingue per le quali è necessa Se si modificano i tipi di parametro di {0}, è necessario riavviare l'applicazione. + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application Se si modifica l'attributo pseudo-personalizzato '{0}' di {1}, è necessario riavviare l'applicazione @@ -1350,6 +1360,11 @@ Assicurarsi di usare l'identificatore "tt" per le lingue per le quali è necessa Rilevata probabile stringa JSON + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array Proprietà non consentite in una matrice @@ -3628,6 +3643,11 @@ Se l'identificatore di formato "d" viene usato senza altri identificatori di for L'identificatore di formato personalizzato "dddd" (più qualsiasi numero di identificatori "d" aggiuntivi) rappresenta il nome esteso del giorno della settimana. Il nome localizzato del giorno della settimana viene recuperato dalla proprietà DateTimeFormatInfo.DayNames delle impostazioni cultura correnti o specificate. + + default> + default> + + discard variabile discard diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf index 8af8702ddeb..9751a5bad4b 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf @@ -450,6 +450,16 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma {0} のパラメーターの種類を変更するには、アプリケーションを再起動する必要があります。 + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application {0} の擬似カスタム属性 '{1}' を変更するには、アプリケーションを再起動する必要があります @@ -1350,6 +1360,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma JSON の可能性のある文字列が検出されました + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array 配列ではプロパティは使用できません @@ -3628,6 +3643,11 @@ If the "d" format specifier is used without other custom format specifiers, it's "dddd" カスタム書式指定子 (任意の数の "d" 指定子を追加できます) は、曜日の完全名を表します。曜日のローカライズされた名前は、現在の、または指定したカルチャの DateTimeFormatInfo.DayNames プロパティから取得されます。 + + default> + default> + + discard 破棄 diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf index 2824699a97b..f8bfe41bae4 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf @@ -450,6 +450,16 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma {0}의 매개 변수 유형을 변경하려면 애플리케이션을 다시 시작해야 합니다. + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application {1}의 허위 사용자 지정 특성 '{0}'을(를) 변경하려면 애플리케이션을 다시 시작해야 합니다. @@ -1350,6 +1360,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 가능한 JSON 문자열이 탐지됨 + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array 배열에는 속성을 사용할 수 없습니다. @@ -3628,6 +3643,11 @@ If the "d" format specifier is used without other custom format specifiers, it's "dddd" 사용자 지정 형식 지정자(및 임의 개수의 추가 "d" 지정자)는 요일의 전체 이름을 나타냅니다. 요일의 지역화된 이름은 현재 문화권 또는 지정된 문화권의 DateTimeFormatInfo.DayNames 속성에서 검색됩니다. + + default> + default> + + discard 무시 항목 diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf index 7111aa3e62a..666306e98bd 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf @@ -450,6 +450,16 @@ Pamiętaj, aby nie używać specyfikatora „tt” dla wszystkich języków, w k Zmiana typów parametrów elementów {0} wymaga ponownego uruchomienia aplikacji. + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application Zmiana atrybutu pseudoniestandardowego elementu „{0}” z {1} wymaga ponownego uruchomienia aplikacji @@ -1350,6 +1360,11 @@ Pamiętaj, aby nie używać specyfikatora „tt” dla wszystkich języków, w k Wykryto prawdopodobnie ciąg JSON + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array Właściwości niedozwolone w tablicy @@ -3628,6 +3643,11 @@ Jeśli specyfikator formatu „d” zostanie użyty bez innych indywidualnych sp Indywidualny specyfikator formatu „dddd” (wraz z dowolną liczbą dodatkowych specyfikatorów „d”) reprezentuje pełną nazwę dnia tygodnia. Zlokalizowana nazwa dnia tygodnia jest pobierana z właściwości DateTimeFormatInfo.DayNames bieżącej lub określonej kultury. + + default> + default> + + discard odrzuć diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf index 3eaf8d35ad4..107cec3b69f 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf @@ -450,6 +450,16 @@ Verifique se o especificador "tt" foi usado para idiomas para os quais é necess A alteração dos tipos de parâmetro de {0} requer o reinício do aplicativo. + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application Alterar o atributo pseudo-personalizado '{0}' de {1} requer o reinício do aplicativo @@ -1350,6 +1360,11 @@ Verifique se o especificador "tt" foi usado para idiomas para os quais é necess Provável cadeia de caracteres JSON detectada + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array Propriedades não permitidas em uma matriz @@ -3628,6 +3643,11 @@ Se o especificador de formato "d" for usado sem outros especificadores de format O especificador de formato personalizado "dddd" (mais qualquer número de especificadores "d" adicionais) representa o nome completo do dia da semana. O nome localizado do dia da semana é recuperado da propriedade DateTimeFormatInfo.DayNames da cultura atual ou especificada. + + default> + default> + + discard discard diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf index d09cff14956..9b1d6388d44 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf @@ -450,6 +450,16 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma Для изменения типов параметров {0} требуется перезапустить приложение. + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application Для изменения псевдонастраиваемого атрибута "{0}" для {1} требуется перезапустить приложение. @@ -1350,6 +1360,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma Обнаружена возможная строка JSON + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array Свойства не разрешены в массиве @@ -3628,6 +3643,11 @@ If the "d" format specifier is used without other custom format specifiers, it's Описатель пользовательского формата "dddd" (плюс любое число дополнительных описателей "d") представляет полное название дня недели. Локализованное название дня недели извлекается из свойства DateTimeFormatInfo.DayNames текущих или заданных языка и региональных параметров. + + default> + default> + + discard отменить diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf index d7943aef7b3..eff0b6ed434 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf @@ -450,6 +450,16 @@ AM ve PM arasındaki farkın korunmasının gerekli olduğu diller için "tt" be {0} öğesinin parametre türlerinin değiştirilmesi, uygulamanın yeniden başlatılmasını gerektirir. + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application {1} öğesinin '{0}' sahte özel özniteliğinin değiştirilmesi, uygulamanın yeniden başlatılmasını gerektirir @@ -1350,6 +1360,11 @@ AM ve PM arasındaki farkın korunmasının gerekli olduğu diller için "tt" be Olası JSON dizesi algılandı + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array Dizide özelliklere izin verilmiyor @@ -3628,6 +3643,11 @@ If the "d" format specifier is used without other custom format specifiers, it's "dddd" özel biçim belirticisi (ve herhangi bir sayıda "d" belirticisi) haftanın gününün tam adını temsil eder. Haftanın gününün yerelleştirilmiş adı, geçerli veya belirtilen kültürün DateTimeFormatInfo.DayNames özelliğinden alınır. + + default> + default> + + discard at diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf index c4751ccee9a..f182f12a29c 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf @@ -450,6 +450,16 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 更改 {0} 的参数类型需要重启应用程序。 + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application 更改 {1} 的伪自定义属性“{0}”需要重启应用程序 @@ -1350,6 +1360,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 检测到可能的 JSON 字符串 + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array 数组中不允许有属性 @@ -3628,6 +3643,11 @@ If the "d" format specifier is used without other custom format specifiers, it's "dddd" 自定义格式说明符(另加任意数量的其他 "d" 说明符)表示一周中某天的完整名称。可从当前或指定区域性的 DateTimeFormatInfo.DayNames 属性中检索一周中某天的本地化名称。 + + default> + default> + + discard 放弃 diff --git a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf index dc551e792c7..5b5af86284d 100644 --- a/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf +++ b/src/roslyn/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf @@ -450,6 +450,16 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 變更 {0} 的參數類型需要重新啟動應用程式。 + + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + Changing project or package reference caused the identity of referenced assembly to change from '{0}' to '{1}', which requires restarting the application. + + + + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + Changing project setting '{0}' from '{1}' to '{2}' requires restarting the application. + + Changing pseudo-custom attribute '{0}' of {1} requires restarting the application 變更 {1} 的虛擬自訂屬性 '{0}' 需要重新啟動應用程式 @@ -1350,6 +1360,11 @@ Make sure to use the "tt" specifier for languages for which it's necessary to ma 偵測到可能的 JSON 字串 + + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + Project references mutliple assemblies of the same simple name '{0}': {1}. Changing a reference to such an assembly requires restarting the application. + + Properties not allowed in an array 在陣列中不允許屬性 @@ -3628,6 +3643,11 @@ If the "d" format specifier is used without other custom format specifiers, it's "dddd" 自訂格式規範 (加上任意數目的其他 "d" 規範) 代表星期幾的完整名稱。系統會從目前文化特性或指定文化特性的 DateTimeFormatInfo.DayNames 屬性,擷取星期幾的當地語系化名稱。 + + default> + default> + + discard 捨棄 diff --git a/src/roslyn/src/Features/DiagnosticsTestUtilities/CodeActions/VisualBasicCodeRefactoringVerifier`1.cs b/src/roslyn/src/Features/DiagnosticsTestUtilities/CodeActions/VisualBasicCodeRefactoringVerifier`1.cs index 1a31a8b1f8b..d45791c0dbb 100644 --- a/src/roslyn/src/Features/DiagnosticsTestUtilities/CodeActions/VisualBasicCodeRefactoringVerifier`1.cs +++ b/src/roslyn/src/Features/DiagnosticsTestUtilities/CodeActions/VisualBasicCodeRefactoringVerifier`1.cs @@ -12,6 +12,13 @@ namespace Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions; public static partial class VisualBasicCodeRefactoringVerifier where TCodeRefactoring : CodeRefactoringProvider, new() { + /// + public static Task VerifyRefactoringAsync( + string source) + { + return VerifyRefactoringAsync(source, DiagnosticResult.EmptyDiagnosticResults, source); + } + /// public static Task VerifyRefactoringAsync(string source, string fixedSource) { diff --git a/src/roslyn/src/Features/ExternalAccess/Copilot/Internal/SemanticSearch/SemanticSearchCopilotServiceWrapper.cs b/src/roslyn/src/Features/ExternalAccess/Copilot/Internal/SemanticSearch/SemanticSearchCopilotServiceWrapper.cs deleted file mode 100644 index 472cbc8d06f..00000000000 --- a/src/roslyn/src/Features/ExternalAccess/Copilot/Internal/SemanticSearch/SemanticSearchCopilotServiceWrapper.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; -using System.Composition; -using System.Threading; -using System.Threading.Tasks; -using Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch; -using Microsoft.CodeAnalysis.Host.Mef; -using Microsoft.CodeAnalysis.SemanticSearch; - -namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.Internal.SemanticSearch; - -[Export(typeof(ISemanticSearchCopilotService)), Shared] -[method: ImportingConstructor] -[method: Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] -internal sealed class SemanticSearchCopilotServiceWrapper( - [Import(AllowDefault = true)] Lazy? impl) : ISemanticSearchCopilotService -{ - bool ISemanticSearchCopilotService.IsAvailable - => impl != null; - - async ValueTask ISemanticSearchCopilotService.TryGetQueryAsync(string text, SemanticSearchCopilotContext context, CancellationToken cancellationToken) - { - Contract.ThrowIfNull(impl); - - var result = await impl.Value.TryGetQueryAsync( - text, - new SemanticSearchCopilotContextImpl() - { - ModelName = context.ModelName, - AvailablePackages = context.AvailablePackages, - }, - cancellationToken).ConfigureAwait(false); - - return new SemanticSearchCopilotGeneratedQuery() - { - IsError = result.IsError, - Text = result.Text, - }; - } -} diff --git a/src/roslyn/src/Features/ExternalAccess/Copilot/SemanticSearch/ISemanticSearchCopilotServiceImpl.cs b/src/roslyn/src/Features/ExternalAccess/Copilot/SemanticSearch/ISemanticSearchCopilotServiceImpl.cs deleted file mode 100644 index 4b3a34a53bb..00000000000 --- a/src/roslyn/src/Features/ExternalAccess/Copilot/SemanticSearch/ISemanticSearchCopilotServiceImpl.cs +++ /dev/null @@ -1,38 +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.Threading; -using System.Threading.Tasks; - -namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch; - -internal interface ISemanticSearchCopilotServiceImpl -{ - ValueTask TryGetQueryAsync(string text, SemanticSearchCopilotContextImpl context, CancellationToken cancellationToken); -} - -internal sealed class SemanticSearchCopilotContextImpl -{ - public required string ModelName { get; init; } - - /// - /// List of package names and versions that to include in the prompt. - /// - public required IEnumerable<(string name, Version version)> AvailablePackages { get; init; } -} - -internal readonly struct SemanticSearchCopilotGeneratedQueryImpl -{ - /// - /// True if is an error message. - /// - public required bool IsError { get; init; } - - /// - /// The generated code or an error message. - /// - public required string Text { get; init; } -} diff --git a/src/roslyn/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs b/src/roslyn/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs index e0273bb6ac7..ac6178629ce 100644 --- a/src/roslyn/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs +++ b/src/roslyn/src/Features/Test/EditAndContinue/EditAndContinueWorkspaceServiceTests.cs @@ -300,6 +300,439 @@ class C { int Y => 2; } EndDebuggingSession(debuggingSession); } + [Theory] + [CombinatorialData] + internal async Task Project_ParseOptions( + [CombinatorialValues(ProjectSettingKind.LangVersion, ProjectSettingKind.Features, ProjectSettingKind.DefineConstants)] ProjectSettingKind settingKind, + [CombinatorialValues(LanguageNames.CSharp, LanguageNames.VisualBasic)] string language) + { + var source = language == LanguageNames.CSharp + ? """ + class C; + """ + : """ + Class C + End Class + """; + + var sourceFile1 = Temp.CreateFile().WriteAllText(source, Encoding.UTF8); + + using var w = CreateWorkspace(out var solution, out var service); + + solution = solution. + AddTestProject("test", language, out var projectId). + AddTestDocument(source, sourceFile1.Path, out var documentId).Project.Solution; + + var project = solution.GetRequiredProject(projectId); + + EmitAndLoadLibraryToDebuggee(project); + + var debuggingSession = await StartDebuggingSessionAsync(service, solution); + + var (code, settingName) = settingKind switch + { + ProjectSettingKind.LangVersion => ("ENC1100", "LangVersion"), + ProjectSettingKind.Features => ("ENC1101", "Features"), + ProjectSettingKind.DefineConstants => ("ENC1102", "DefineConstants"), + _ => throw ExceptionUtilities.UnexpectedValue(settingKind) + }; + + ParseOptions newOptions; + string oldValue; + string newValue; + + if (language == LanguageNames.CSharp) + { + var oldOptions = (CSharpParseOptions)project.ParseOptions; + + (newOptions, oldValue, newValue) = settingKind switch + { + ProjectSettingKind.LangVersion => (oldOptions.WithLanguageVersion(CSharp.LanguageVersion.CSharp11), "default", "11.0"), + ProjectSettingKind.Features => (oldOptions.WithFeatures([new("f1", "1"), new("f2", "2")]), "noRefSafetyRulesAttribute=true", "f1=1,f2=2"), + ProjectSettingKind.DefineConstants => (oldOptions.WithPreprocessorSymbols("S1", "S2"), "", "S1,S2"), + _ => throw ExceptionUtilities.UnexpectedValue(settingKind) + }; + } + else + { + var oldOptions = (VisualBasic.VisualBasicParseOptions)project.ParseOptions; + + (newOptions, oldValue, newValue) = settingKind switch + { + ProjectSettingKind.LangVersion => (oldOptions.WithLanguageVersion(VisualBasic.LanguageVersion.VisualBasic11), "default", "11"), + ProjectSettingKind.Features => (oldOptions.WithFeatures([new("f1", "1"), new("f2", "2")]), "", "f1=1,f2=2"), + ProjectSettingKind.DefineConstants => (oldOptions.WithPreprocessorSymbols(new("S1", 1), new("S2", 2)), "_MYTYPE=Empty", "S1=1,S2=2"), + _ => throw ExceptionUtilities.UnexpectedValue(settingKind) + }; + } + + solution = project.WithParseOptions(newOptions).Solution; + + // Rude edits not reported for document, will be reported when emitting updates: + var diagnostics = await service.GetDocumentDiagnosticsAsync(solution.GetRequiredDocument(documentId), s_noActiveSpans, CancellationToken.None); + AssertEx.Empty(diagnostics); + + var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true); + Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status); + Assert.Empty(results.ModuleUpdates.Updates); + + AssertEx.Equal( + [ + $"test: : Error {code}: {string.Format(FeaturesResources.Changing_project_setting_0_from_1_to_2_requires_restarting_the_application, settingName, oldValue, newValue)}" + ], InspectDiagnostics(results.Diagnostics)); + + debuggingSession.DiscardSolutionUpdate(); + + EndDebuggingSession(debuggingSession); + } + + [Theory] + [CombinatorialData] + internal async Task Project_CompilationOptions( + [CombinatorialValues( + ProjectSettingKind.CheckForOverflowUnderflow, + ProjectSettingKind.OutputType, + ProjectSettingKind.StartupObject, + ProjectSettingKind.ModuleAssemblyName, + ProjectSettingKind.Platform, + ProjectSettingKind.OptimizationLevel + )] ProjectSettingKind settingKind, + [CombinatorialValues(LanguageNames.CSharp, LanguageNames.VisualBasic)] string language) + { + var source = language == LanguageNames.CSharp + ? """ + class C; + """ + : """ + Class C + End Class + """; + + var sourceFile1 = Temp.CreateFile().WriteAllText(source, Encoding.UTF8); + + using var w = CreateWorkspace(out var solution, out var service); + + solution = solution. + AddTestProject("test", language, out var projectId). + AddTestDocument(source, sourceFile1.Path, out var documentId).Project.Solution; + + var project = solution.GetRequiredProject(projectId); + + EmitAndLoadLibraryToDebuggee(project); + + var debuggingSession = await StartDebuggingSessionAsync(service, solution); + + var (code, settingName, isWarning) = settingKind switch + { + ProjectSettingKind.CheckForOverflowUnderflow => ("ENC1103", "CheckForOverflowUnderflow", isWarning: false), + ProjectSettingKind.OutputType => ("ENC1104", "OutputType", isWarning: true), + ProjectSettingKind.StartupObject => ("ENC1105", "StartupObject", isWarning: true), + ProjectSettingKind.ModuleAssemblyName => ("ENC1109", "ModuleAssemblyName", isWarning: false), + ProjectSettingKind.Platform => ("ENC1111", "Platform", isWarning: true), + ProjectSettingKind.OptimizationLevel => ("ENC1112", "OptimizationLevel", isWarning: false), + _ => throw ExceptionUtilities.UnexpectedValue(settingKind) + }; + + CompilationOptions newOptions; + string oldValue; + string newValue; + + var oldOptions = project.CompilationOptions; + var defaultOverflowChecks = oldOptions.CheckOverflow; + + (newOptions, oldValue, newValue) = settingKind switch + { + ProjectSettingKind.CheckForOverflowUnderflow => (oldOptions.WithOverflowChecks(!defaultOverflowChecks), defaultOverflowChecks.ToString(), (!defaultOverflowChecks).ToString()), + ProjectSettingKind.OutputType => (oldOptions.WithOutputKind(OutputKind.WindowsRuntimeApplication), "Library", "AppContainerExe"), + ProjectSettingKind.StartupObject => (oldOptions.WithMainTypeName("NewProgram"), $"<{FeaturesResources.@default}>", "NewProgram"), + ProjectSettingKind.ModuleAssemblyName => (oldOptions.WithModuleName("mod"), $"<{FeaturesResources.@default}>", "mod"), + ProjectSettingKind.Platform => (oldOptions.WithPlatform(Platform.Arm64), "AnyCpu", "Arm64"), + ProjectSettingKind.OptimizationLevel => (oldOptions.WithOptimizationLevel(OptimizationLevel.Release), "Debug", "Release"), + _ => throw ExceptionUtilities.UnexpectedValue(settingKind) + }; + + solution = project.WithCompilationOptions(newOptions).Solution; + + // Rude edits not reported for document, will be reported when emitting updates: + var diagnostics = await service.GetDocumentDiagnosticsAsync(solution.GetRequiredDocument(documentId), s_noActiveSpans, CancellationToken.None); + AssertEx.Empty(diagnostics); + + var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true); + Assert.Equal(isWarning ? ModuleUpdateStatus.None : ModuleUpdateStatus.Ready, results.ModuleUpdates.Status); + Assert.Empty(results.ModuleUpdates.Updates); + + AssertEx.Equal( + [ + $"test: : {(isWarning ? "Warning" : "Error")} {code}: {string.Format(FeaturesResources.Changing_project_setting_0_from_1_to_2_requires_restarting_the_application, settingName, oldValue, newValue)}" + ], InspectDiagnostics(results.Diagnostics)); + + if (!isWarning) + { + debuggingSession.DiscardSolutionUpdate(); + } + + EndDebuggingSession(debuggingSession); + } + + [Theory] + [InlineData(ProjectSettingKind.RootNamespace)] + [InlineData(ProjectSettingKind.OptionStrict)] + [InlineData(ProjectSettingKind.OptionInfer)] + [InlineData(ProjectSettingKind.OptionExplicit)] + [InlineData(ProjectSettingKind.OptionCompare)] + internal async Task Project_CompilationOptions_VB(ProjectSettingKind settingKind) + { + var source = """ + Class C + End Class + """; + + var sourceFile1 = Temp.CreateFile().WriteAllText(source, Encoding.UTF8); + + using var w = CreateWorkspace(out var solution, out var service); + + solution = solution. + AddTestProject("test", LanguageNames.VisualBasic, out var projectId). + AddTestDocument(source, sourceFile1.Path, out var documentId).Project.Solution; + + var project = solution.GetRequiredProject(projectId); + + EmitAndLoadLibraryToDebuggee(project); + + var debuggingSession = await StartDebuggingSessionAsync(service, solution); + + var (code, settingName) = settingKind switch + { + ProjectSettingKind.RootNamespace => ("ENC1150", "RootNamespace"), + ProjectSettingKind.OptionStrict => ("ENC1151", "OptionStrict"), + ProjectSettingKind.OptionInfer => ("ENC1152", "OptionInfer"), + ProjectSettingKind.OptionExplicit => ("ENC1153", "OptionExplicit"), + ProjectSettingKind.OptionCompare => ("ENC1154", "OptionCompare"), + _ => throw ExceptionUtilities.UnexpectedValue(settingKind) + }; + + CompilationOptions newOptions; + string oldValue; + string newValue; + + var oldOptions = (VisualBasic.VisualBasicCompilationOptions)project.CompilationOptions; + + (newOptions, oldValue, newValue) = settingKind switch + { + ProjectSettingKind.RootNamespace => (oldOptions.WithRootNamespace("N"), "", "N"), + ProjectSettingKind.OptionStrict => (oldOptions.WithOptionStrict(VisualBasic.OptionStrict.On), "Off", "On"), + ProjectSettingKind.OptionInfer => (oldOptions.WithOptionInfer(false), "On", "Off"), + ProjectSettingKind.OptionExplicit => (oldOptions.WithOptionExplicit(false), "On", "Off"), + ProjectSettingKind.OptionCompare => (oldOptions.WithOptionCompareText(true), "Binary", "Text"), + _ => throw ExceptionUtilities.UnexpectedValue(settingKind) + }; + + solution = project.WithCompilationOptions(newOptions).Solution; + + // Rude edits not reported for document, will be reported when emitting updates: + var diagnostics = await service.GetDocumentDiagnosticsAsync(solution.GetRequiredDocument(documentId), s_noActiveSpans, CancellationToken.None); + AssertEx.Empty(diagnostics); + + var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true); + Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status); + Assert.Empty(results.ModuleUpdates.Updates); + + AssertEx.Equal( + [ + $"test: : Error {code}: {string.Format(FeaturesResources.Changing_project_setting_0_from_1_to_2_requires_restarting_the_application, settingName, oldValue, newValue)}" + ], InspectDiagnostics(results.Diagnostics)); + + debuggingSession.DiscardSolutionUpdate(); + EndDebuggingSession(debuggingSession); + } + + private static MetadataReference EmitLibraryReference(Version version, bool useStrongName = false) + { + var libSource = $$""" + [assembly: System.Reflection.AssemblyVersion("{{version}}")] + public class Lib; + """; + + var libCompilation = CSharpCompilation.Create( + assemblyName: "Lib", + syntaxTrees: [SyntaxFactory.ParseSyntaxTree(libSource, options: TestOptions.Regular, path: "Lib.cs", Encoding.UTF8)], + references: TargetFrameworkUtil.GetReferences(TargetFramework.NetStandard20), + useStrongName ? TestOptions.SigningDebugDll.WithCryptoKeyFile(SigningTestHelpers.KeyPairFile) : TestOptions.DebugDll); + + return libCompilation.EmitToImageReference(); + } + + [Fact] + internal async Task Project_MetadataReferences() + { + var source = "class C;"; + var sourceFile = Temp.CreateFile().WriteAllText(source, Encoding.UTF8); + + var libV1 = EmitLibraryReference(new Version(1, 0, 0, 0)); + var libV2 = EmitLibraryReference(new Version(2, 0, 0, 0)); + + using var w = CreateWorkspace(out var solution, out var service); + + solution = solution. + AddTestProject("test", out var projectId). + AddMetadataReference(libV1). + AddTestDocument(source, sourceFile.Path, out var documentId).Project.Solution; + + var project = solution.GetRequiredProject(projectId); + + EmitAndLoadLibraryToDebuggee(project); + + var debuggingSession = await StartDebuggingSessionAsync(service, solution); + + // change version of the dependency: + solution = project.RemoveMetadataReference(libV1).AddMetadataReference(libV2).Solution; + + // Rude edits not reported for document, will be reported when emitting updates: + var diagnostics = await service.GetDocumentDiagnosticsAsync(solution.GetRequiredDocument(documentId), s_noActiveSpans, CancellationToken.None); + AssertEx.Empty(diagnostics); + + var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true); + Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status); + Assert.Empty(results.ModuleUpdates.Updates); + + AssertEx.Equal( + [ + $"test: : Error ENC1099: {string.Format( + FeaturesResources.Changing_project_or_package_reference_caused_the_identity_of_referenced_assembly_to_change_from_0_to_1_which_requires_restarting_the_application, + "Lib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", + "Lib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null")}" + ], InspectDiagnostics(results.Diagnostics)); + + debuggingSession.DiscardSolutionUpdate(); + + EndDebuggingSession(debuggingSession); + } + + [Fact] + internal async Task Project_MetadataReferences_RemoveAdd() + { + var source = "class C;"; + var sourceFile = Temp.CreateFile().WriteAllText(source, Encoding.UTF8); + + var libV1 = EmitLibraryReference(new Version(1, 0, 0, 0)); + var libV2 = EmitLibraryReference(new Version(2, 0, 0, 0)); + + using var w = CreateWorkspace(out var solution, out var service); + + solution = solution. + AddTestProject("test", out var projectId). + AddMetadataReference(libV1). + AddTestDocument(source, sourceFile.Path, out var documentId).Project.Solution; + + var project = solution.GetRequiredProject(projectId); + + EmitAndLoadLibraryToDebuggee(project); + + var debuggingSession = await StartDebuggingSessionAsync(service, solution); + + // remove dependency: + solution = project.RemoveMetadataReference(libV1).Solution; + + var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true); + Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status); + Assert.Empty(results.ModuleUpdates.Updates); + Assert.Empty(results.Diagnostics); + + // add newer version: + solution = project.AddMetadataReference(libV2).Solution; + + results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true); + Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status); + Assert.Empty(results.ModuleUpdates.Updates); + + AssertEx.Equal( + [ + $"test: : Error ENC1099: {string.Format( + FeaturesResources.Changing_project_or_package_reference_caused_the_identity_of_referenced_assembly_to_change_from_0_to_1_which_requires_restarting_the_application, + "Lib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", + "Lib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null")}" + ], InspectDiagnostics(results.Diagnostics)); + + debuggingSession.DiscardSolutionUpdate(); + + EndDebuggingSession(debuggingSession); + } + + [Fact] + internal async Task Project_MetadataReferences_Add() + { + var source = "class C;"; + var sourceFile = Temp.CreateFile().WriteAllText(source, Encoding.UTF8); + + var libV1 = EmitLibraryReference(new Version(1, 0, 0, 0)); + + using var w = CreateWorkspace(out var solution, out var service); + + solution = solution. + AddTestProject("test", out var projectId). + AddTestDocument(source, sourceFile.Path, out var documentId).Project.Solution; + + var project = solution.GetRequiredProject(projectId); + + EmitAndLoadLibraryToDebuggee(project); + + var debuggingSession = await StartDebuggingSessionAsync(service, solution); + + // add dependency: + solution = project.AddMetadataReference(libV1).Solution; + + var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true); + Assert.Equal(ModuleUpdateStatus.None, results.ModuleUpdates.Status); + Assert.Empty(results.ModuleUpdates.Updates); + Assert.Empty(results.Diagnostics); + + EndDebuggingSession(debuggingSession); + } + + [Fact] + internal async Task Project_MetadataReferences_MultipleVersions() + { + var source = "class C;"; + var sourceFile = Temp.CreateFile().WriteAllText(source, Encoding.UTF8); + + var libV1 = EmitLibraryReference(new Version(1, 0, 0, 0), useStrongName: true); + var libV2 = EmitLibraryReference(new Version(2, 0, 0, 0), useStrongName: true); + var libV3 = EmitLibraryReference(new Version(3, 0, 0, 0), useStrongName: true); + + using var w = CreateWorkspace(out var solution, out var service); + + solution = solution. + AddTestProject("test", out var projectId). + AddMetadataReference(libV1). + AddMetadataReference(libV2). + AddTestDocument(source, sourceFile.Path, out var documentId).Project.Solution; + + var project = solution.GetRequiredProject(projectId); + + EmitAndLoadLibraryToDebuggee(project); + + var debuggingSession = await StartDebuggingSessionAsync(service, solution); + + // add version 3: + solution = project.AddMetadataReference(libV3).Solution; + + var results = await EmitSolutionUpdateAsync(debuggingSession, solution, allowPartialUpdate: true); + Assert.Equal(ModuleUpdateStatus.Ready, results.ModuleUpdates.Status); + Assert.Empty(results.ModuleUpdates.Updates); + + AssertEx.Equal( + [ + $"test: : Error ENC1098: {string.Format( + FeaturesResources.Project_references_mutliple_assemblies_of_the_same_simple_name_0_1_Changing_a_reference_to_such_an_assembly_requires_restarting_the_application, + "Lib", + "'Lib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ce65828c82a341f2', 'Lib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=ce65828c82a341f2'")}" + ], InspectDiagnostics(results.Diagnostics)); + + debuggingSession.DiscardSolutionUpdate(); + + EndDebuggingSession(debuggingSession); + } + [Fact] public async Task DesignTimeOnlyDocument() { @@ -661,10 +1094,11 @@ public async Task ErrorReadingSourceFile() debuggingSession.DiscardSolutionUpdate(); EndDebuggingSession(debuggingSession); - AssertEx.Equal( + AssertEx.SequenceEqual( [ "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=1|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", - "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=True|Capabilities=31|ProjectIdsWithAppliedChanges=|ProjectIdsWithUpdatedBaselines=" + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=True|HadValidInsignificantChanges=False|RudeEditsCount=0|EmitDeltaErrorIdCount=1|InBreakState=True|Capabilities=31|ProjectIdsWithAppliedChanges=|ProjectIdsWithUpdatedBaselines=", + "Debugging_EncSession_EditSession_EmitDeltaErrorId: SessionId=1|EditSessionId=2|ErrorId=ENC1006" ], _telemetryLog); } @@ -1742,7 +2176,7 @@ public async Task HasChanges_Documents(TextDocumentKind documentKind) EnterBreakState(debuggingSession); Assert.Equal(1, generatorExecutionCount); - var documentDifferences = new ProjectDocumentDifferences(); + var projectDifferences = new ProjectDifferences(); // // Add document @@ -1771,10 +2205,10 @@ public async Task HasChanges_Documents(TextDocumentKind documentKind) await EditSession.GetChangedDocumentsAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), CancellationToken.None).ToImmutableArrayAsync(CancellationToken.None)); var diagnostics = new ArrayBuilder(); - await EditSession.GetDocumentDifferencesAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), documentDifferences, diagnostics, CancellationToken.None); + await EditSession.GetProjectDifferencesAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), projectDifferences, diagnostics, CancellationToken.None); Assert.Empty(diagnostics); - Assert.Empty(documentDifferences.Deleted); - AssertEx.Equal(documentKind == TextDocumentKind.Document ? [documentId, generatedDocumentId] : [generatedDocumentId], documentDifferences.ChangedOrAdded.Select(d => d.Id)); + Assert.Empty(projectDifferences.DeletedDocuments); + AssertEx.Equal(documentKind == TextDocumentKind.Document ? [documentId, generatedDocumentId] : [generatedDocumentId], projectDifferences.ChangedOrAddedDocuments.Select(d => d.Id)); Assert.Equal(1, generatorExecutionCount); @@ -1801,9 +2235,9 @@ public async Task HasChanges_Documents(TextDocumentKind documentKind) AssertEx.Equal(documentKind == TextDocumentKind.Document ? new[] { documentId } : [], await EditSession.GetChangedDocumentsAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), CancellationToken.None).ToImmutableArrayAsync(CancellationToken.None)); - await EditSession.GetDocumentDifferencesAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), documentDifferences, diagnostics, CancellationToken.None); + await EditSession.GetProjectDifferencesAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), projectDifferences, diagnostics, CancellationToken.None); Assert.Empty(diagnostics); - Assert.True(documentDifferences.IsEmpty); + Assert.True(projectDifferences.IsEmpty); Assert.Equal(1, generatorExecutionCount); @@ -1826,10 +2260,10 @@ public async Task HasChanges_Documents(TextDocumentKind documentKind) AssertEx.Equal(documentKind == TextDocumentKind.Document ? [documentId, generatedDocumentId] : [generatedDocumentId], await EditSession.GetChangedDocumentsAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), CancellationToken.None).ToImmutableArrayAsync(CancellationToken.None)); - await EditSession.GetDocumentDifferencesAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), documentDifferences, diagnostics, CancellationToken.None); + await EditSession.GetProjectDifferencesAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), projectDifferences, diagnostics, CancellationToken.None); Assert.Empty(diagnostics); - Assert.Empty(documentDifferences.Deleted); - AssertEx.Equal(documentKind == TextDocumentKind.Document ? [documentId, generatedDocumentId] : [generatedDocumentId], documentDifferences.ChangedOrAdded.Select(d => d.Id)); + Assert.Empty(projectDifferences.DeletedDocuments); + AssertEx.Equal(documentKind == TextDocumentKind.Document ? [documentId, generatedDocumentId] : [generatedDocumentId], projectDifferences.ChangedOrAddedDocuments.Select(d => d.Id)); Assert.Equal(1, generatorExecutionCount); @@ -1854,19 +2288,19 @@ public async Task HasChanges_Documents(TextDocumentKind documentKind) AssertEx.Equal([generatedDocumentId], await EditSession.GetChangedDocumentsAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), CancellationToken.None).ToImmutableArrayAsync(CancellationToken.None)); - await EditSession.GetDocumentDifferencesAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), documentDifferences, diagnostics, CancellationToken.None); + await EditSession.GetProjectDifferencesAsync(log, oldSolution.GetProject(projectId), solution.GetProject(projectId), projectDifferences, diagnostics, CancellationToken.None); Assert.Empty(diagnostics); if (documentKind == TextDocumentKind.Document) { - AssertEx.Equal([documentId], documentDifferences.Deleted.Select(d => d.Id)); + AssertEx.Equal([documentId], projectDifferences.DeletedDocuments.Select(d => d.Id)); } else { - AssertEx.Empty(documentDifferences.Deleted); + AssertEx.Empty(projectDifferences.DeletedDocuments); } - AssertEx.Equal([generatedDocumentId], documentDifferences.ChangedOrAdded.Select(d => d.Id)); + AssertEx.Equal([generatedDocumentId], projectDifferences.ChangedOrAddedDocuments.Select(d => d.Id)); Assert.Equal(1, generatorExecutionCount); } @@ -1919,7 +2353,7 @@ public async Task HasChanges_SourceGeneratorFailure() var debuggingSession = await StartDebuggingSessionAsync(service, solution); EnterBreakState(debuggingSession); - var documentDiffences = new ProjectDocumentDifferences(); + var diffences = new ProjectDifferences(); // // Update document content @@ -1937,10 +2371,10 @@ public async Task HasChanges_SourceGeneratorFailure() AssertEx.Empty(await EditSession.GetChangedDocumentsAsync(log, oldProject, project, CancellationToken.None).ToImmutableArrayAsync(CancellationToken.None)); var diagnostics = new ArrayBuilder(); - await EditSession.GetDocumentDifferencesAsync(log, oldProject, project, documentDiffences, diagnostics, CancellationToken.None); + await EditSession.GetProjectDifferencesAsync(log, oldProject, project, diffences, diagnostics, CancellationToken.None); Assert.Contains("System.InvalidOperationException: Source generator failed", diagnostics.Single().GetMessage()); - AssertEx.Empty(documentDiffences.ChangedOrAdded); - AssertEx.Equal(["generated.cs"], documentDiffences.Deleted.Select(d => d.Name)); + AssertEx.Empty(diffences.ChangedOrAddedDocuments); + AssertEx.Equal(["generated.cs"], diffences.DeletedDocuments.Select(d => d.Name)); Assert.Equal(2, generatorExecutionCount); @@ -3437,7 +3871,8 @@ public async Task ValidInsignificantChange() AssertEx.SequenceEqual( [ - "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=0|EmptyHotReloadSessionCount=1", + "Debugging_EncSession: SolutionSessionId={00000000-AAAA-AAAA-AAAA-000000000000}|SessionId=1|SessionCount=0|EmptySessionCount=0|HotReloadSessionCount=1|EmptyHotReloadSessionCount=0", + "Debugging_EncSession_EditSession: SessionId=1|EditSessionId=2|HadCompilationErrors=False|HadRudeEdits=False|HadValidChanges=False|HadValidInsignificantChanges=True|RudeEditsCount=0|EmitDeltaErrorIdCount=0|InBreakState=False|Capabilities=31|ProjectIdsWithAppliedChanges=|ProjectIdsWithUpdatedBaselines=" ], _telemetryLog); } diff --git a/src/roslyn/src/Features/TestUtilities/EditAndContinue/EditAndContinueWorkspaceTestBase.cs b/src/roslyn/src/Features/TestUtilities/EditAndContinue/EditAndContinueWorkspaceTestBase.cs index 3f55d58c5b4..308fc11242d 100644 --- a/src/roslyn/src/Features/TestUtilities/EditAndContinue/EditAndContinueWorkspaceTestBase.cs +++ b/src/roslyn/src/Features/TestUtilities/EditAndContinue/EditAndContinueWorkspaceTestBase.cs @@ -305,12 +305,13 @@ internal Guid EmitAndLoadLibraryToDebuggee(Project project, TargetFramework targ internal Guid EmitAndLoadLibraryToDebuggee( ProjectId projectId, string source, + string language = LanguageNames.CSharp, string? sourceFilePath = null, Encoding? encoding = null, SourceHashAlgorithm checksumAlgorithm = SourceHashAlgorithms.Default, - string assemblyName = "", + string? assemblyName = null, TargetFramework targetFramework = DefaultTargetFramework) - => LoadLibraryToDebuggee(EmitLibrary(projectId, source, sourceFilePath, encoding, checksumAlgorithm, assemblyName, targetFramework: targetFramework)); + => LoadLibraryToDebuggee(EmitLibrary(projectId, source, sourceFilePath, language, encoding, checksumAlgorithm, assemblyName, targetFramework: targetFramework)); internal Guid LoadLibraryToDebuggee(Guid moduleId, ManagedHotReloadAvailability availability = default) { @@ -322,6 +323,7 @@ internal Guid EmitLibrary(Project project, TargetFramework targetFramework = Def => EmitLibrary( project.Id, project.Documents.Select(d => (d.GetTextSynchronously(CancellationToken.None), d.FilePath ?? throw ExceptionUtilities.UnexpectedValue(null))), + project.Language, project.AssemblyName, targetFramework: targetFramework); @@ -329,9 +331,10 @@ internal Guid EmitLibrary( ProjectId projectId, string source, string? sourceFilePath = null, + string language = LanguageNames.CSharp, Encoding? encoding = null, SourceHashAlgorithm checksumAlgorithm = SourceHashAlgorithms.Default, - string assemblyName = "", + string? assemblyName = null, DebugInformationFormat pdbFormat = DebugInformationFormat.PortablePdb, Project? generatorProject = null, string? additionalFileText = null, @@ -340,6 +343,7 @@ internal Guid EmitLibrary( => EmitLibrary( projectId, [(source, sourceFilePath ?? Path.Combine(TempRoot.Root, "test1.cs"))], + language, encoding, checksumAlgorithm, assemblyName, @@ -352,20 +356,20 @@ internal Guid EmitLibrary( internal Guid EmitLibrary( ProjectId projectId, (string content, string filePath)[] sources, + string language = LanguageNames.CSharp, Encoding? encoding = null, SourceHashAlgorithm checksumAlgorithm = SourceHashAlgorithms.Default, - string assemblyName = "", + string? assemblyName = null, DebugInformationFormat pdbFormat = DebugInformationFormat.PortablePdb, Project? generatorProject = null, string? additionalFileText = null, IEnumerable<(string, string)>? analyzerOptions = null, TargetFramework targetFramework = DefaultTargetFramework) { - encoding ??= Encoding.UTF8; - return EmitLibrary( projectId, - sources.Select(source => (SourceText.From(new MemoryStream(encoding.GetBytesWithPreamble(source.content.ToString())), encoding, checksumAlgorithm), source.filePath)), + sources.Select(source => (CreateText(source.content, encoding, checksumAlgorithm), source.filePath)), + language, assemblyName, pdbFormat, generatorProject, @@ -374,34 +378,70 @@ internal Guid EmitLibrary( targetFramework); } + internal static SourceText CreateText(string source, Encoding? encoding = null, SourceHashAlgorithm checksumAlgorithm = SourceHashAlgorithms.Default) + { + encoding ??= Encoding.UTF8; + return SourceText.From(new MemoryStream(encoding.GetBytesWithPreamble(source)), encoding, checksumAlgorithm); + } + internal Guid EmitLibrary( ProjectId projectId, IEnumerable<(SourceText text, string filePath)> sources, - string assemblyName = "", + string language = LanguageNames.CSharp, + string? assemblyName = null, DebugInformationFormat pdbFormat = DebugInformationFormat.PortablePdb, Project? generatorProject = null, string? additionalFileText = null, IEnumerable<(string, string)>? analyzerOptions = null, TargetFramework targetFramework = DefaultTargetFramework) { - var parseOptions = TestOptions.RegularPreview.WithNoRefSafetyRulesAttribute(); + Compilation compilation; + CSharpParseOptions? csParseOptions = null; + VisualBasic.VisualBasicParseOptions? vbParseOptions = null; - var trees = sources.Select(source => SyntaxFactory.ParseSyntaxTree(source.text, parseOptions, source.filePath)); + var references = TargetFrameworkUtil.GetReferences(targetFramework); + assemblyName ??= "TestAssembly"; - Compilation compilation = CSharpTestBase.CreateCompilation(trees.ToArray(), options: TestOptions.DebugDll, targetFramework: targetFramework, assemblyName: assemblyName); + if (language == LanguageNames.CSharp) + { + csParseOptions = TestOptions.RegularPreview.WithNoRefSafetyRulesAttribute(); + var trees = sources.Select(source => SyntaxFactory.ParseSyntaxTree(source.text, csParseOptions, source.filePath)); + compilation = CSharpCompilation.Create(assemblyName, trees, references, TestOptions.DebugDll); + } + else + { + vbParseOptions = VisualBasic.UnitTests.TestOptions.Regular; + var trees = sources.Select(source => VisualBasic.SyntaxFactory.ParseSyntaxTree(source.text, vbParseOptions, source.filePath)); + compilation = VisualBasic.VisualBasicCompilation.Create(assemblyName, trees, references, VisualBasic.UnitTests.TestOptions.DebugDll); + } if (generatorProject != null) { var generators = generatorProject.AnalyzerReferences.SelectMany(r => r.GetGenerators(language: generatorProject.Language)); + var driverOptions = new GeneratorDriverOptions(baseDirectory: generatorProject.CompilationOutputInfo.GetEffectiveGeneratedFilesOutputDirectory()!); var optionsProvider = (analyzerOptions != null) ? new EditAndContinueTestAnalyzerConfigOptionsProvider(analyzerOptions) : null; var additionalTexts = (additionalFileText != null) ? new[] { new InMemoryAdditionalText("additional_file", additionalFileText) } : null; - var generatorDriver = CSharpGeneratorDriver.Create( - generators, - additionalTexts, - parseOptions, - optionsProvider, - driverOptions: new GeneratorDriverOptions(baseDirectory: generatorProject.CompilationOutputInfo.GetEffectiveGeneratedFilesOutputDirectory()!)); + + GeneratorDriver generatorDriver; + if (language == LanguageNames.CSharp) + { + generatorDriver = CSharpGeneratorDriver.Create( + generators, + additionalTexts, + csParseOptions!, + optionsProvider, + driverOptions); + } + else + { + generatorDriver = VisualBasic.VisualBasicGeneratorDriver.Create( + [.. generators], + additionalTexts.ToImmutableArrayOrEmpty(), + vbParseOptions!, + optionsProvider, + driverOptions); + } generatorDriver.RunGeneratorsAndUpdateCompilation(compilation, out var outputCompilation, out var generatorDiagnostics); generatorDiagnostics.Verify(); diff --git a/src/roslyn/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb b/src/roslyn/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb index 3d92612f569..30ce9c4296c 100644 --- a/src/roslyn/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb +++ b/src/roslyn/src/Features/VisualBasic/Portable/EditAndContinue/VisualBasicEditAndContinueAnalyzer.vb @@ -2357,5 +2357,67 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.EditAndContinue End Sub #End Region + + Protected Overrides Iterator Function GetParseOptionsRudeEdits(oldOptions As ParseOptions, newOptions As ParseOptions) As IEnumerable(Of Diagnostic) + For Each rudeEdit In MyBase.GetParseOptionsRudeEdits(oldOptions, newOptions) + Yield rudeEdit + Next + + Dim oldVBOptions = DirectCast(oldOptions, VisualBasicParseOptions) + Dim newVBOptions = DirectCast(newOptions, VisualBasicParseOptions) + + If oldVBOptions.LanguageVersion <> newVBOptions.LanguageVersion Then + Yield CreateProjectRudeEdit(ProjectSettingKind.LangVersion, + oldVBOptions.SpecifiedLanguageVersion.ToDisplayString(), + newVBOptions.SpecifiedLanguageVersion.ToDisplayString()) + End If + + If Not oldVBOptions.PreprocessorSymbols.SequenceEqual(newVBOptions.PreprocessorSymbols) Then + Yield CreateProjectRudeEdit(ProjectSettingKind.DefineConstants, + GetPreprocessorSymbolsDisplay(oldVBOptions.PreprocessorSymbols), + GetPreprocessorSymbolsDisplay(newVBOptions.PreprocessorSymbols)) + End If + End Function + + Private Shared Function GetPreprocessorSymbolsDisplay(symbols As ImmutableArray(Of KeyValuePair(Of String, Object))) As String + Return String.Join(",", symbols.Select(Function(kvp) kvp.Key & "=" & kvp.Value.ToString())) + End Function + + Protected Overrides Iterator Function GetCompilationOptionsRudeEdits(oldOptions As CompilationOptions, newOptions As CompilationOptions) As IEnumerable(Of Diagnostic) + For Each rudeEdit In MyBase.GetCompilationOptionsRudeEdits(oldOptions, newOptions) + Yield rudeEdit + Next + + Dim oldVBOptions = DirectCast(oldOptions, VisualBasicCompilationOptions) + Dim newVBOptions = DirectCast(newOptions, VisualBasicCompilationOptions) + + If oldVBOptions.RootNamespace <> newVBOptions.RootNamespace Then + Yield CreateProjectRudeEdit(ProjectSettingKind.RootNamespace, oldVBOptions.RootNamespace, newVBOptions.RootNamespace) + End If + + If oldVBOptions.OptionStrict <> newVBOptions.OptionStrict Then + Yield CreateProjectRudeEdit(ProjectSettingKind.OptionStrict, oldVBOptions.OptionStrict.ToString(), newVBOptions.OptionStrict.ToString()) + End If + + If oldVBOptions.OptionInfer <> newVBOptions.OptionInfer Then + Yield CreateProjectRudeEdit(ProjectSettingKind.OptionInfer, GetOptionDisplay(oldVBOptions.OptionInfer), GetOptionDisplay(newVBOptions.OptionInfer)) + End If + + If oldVBOptions.OptionExplicit <> newVBOptions.OptionExplicit Then + Yield CreateProjectRudeEdit(ProjectSettingKind.OptionExplicit, GetOptionDisplay(oldVBOptions.OptionExplicit), GetOptionDisplay(newVBOptions.OptionExplicit)) + End If + + If oldVBOptions.OptionCompareText <> newVBOptions.OptionCompareText Then + Yield CreateProjectRudeEdit(ProjectSettingKind.OptionCompare, GetOptionCompareTextDisplay(oldVBOptions.OptionCompareText), GetOptionCompareTextDisplay(newVBOptions.OptionCompareText)) + End If + End Function + + Private Shared Function GetOptionDisplay(value As Boolean) As String + Return If(value, "On", "Off") + End Function + + Private Shared Function GetOptionCompareTextDisplay(value As Boolean) As String + Return If(value, "Text", "Binary") + End Function End Class End Namespace diff --git a/src/roslyn/src/Features/VisualBasicTest/EditAndContinue/VisualBasicEditAndContinueAnalyzerTests.vb b/src/roslyn/src/Features/VisualBasicTest/EditAndContinue/VisualBasicEditAndContinueAnalyzerTests.vb index 27829387115..86c7757678d 100644 --- a/src/roslyn/src/Features/VisualBasicTest/EditAndContinue/VisualBasicEditAndContinueAnalyzerTests.vb +++ b/src/roslyn/src/Features/VisualBasicTest/EditAndContinue/VisualBasicEditAndContinueAnalyzerTests.vb @@ -522,8 +522,9 @@ End Class Dim result = Await AnalyzeDocumentAsync(oldProject, oldDocument) Assert.False(result.HasChanges) - Assert.False(result.HasChangesAndErrors) - Assert.False(result.HasChangesAndSyntaxErrors) + Assert.False(result.AnalysisBlocked) + Assert.False(result.HasBlockingRudeEdits) + Assert.Null(result.SyntaxError) End Using End Function @@ -554,8 +555,9 @@ End Class Dim result = Await AnalyzeDocumentAsync(oldProject, newSolution.GetDocument(documentId)) Assert.False(result.HasChanges) - Assert.False(result.HasChangesAndErrors) - Assert.False(result.HasChangesAndSyntaxErrors) + Assert.False(result.AnalysisBlocked) + Assert.False(result.HasBlockingRudeEdits) + Assert.Null(result.SyntaxError) End Using End Function @@ -578,8 +580,9 @@ End Class Dim result = Await AnalyzeDocumentAsync(oldProject, oldDocument) Assert.False(result.HasChanges) - Assert.False(result.HasChangesAndErrors) - Assert.False(result.HasChangesAndSyntaxErrors) + Assert.False(result.AnalysisBlocked) + Assert.False(result.HasBlockingRudeEdits) + Assert.Null(result.SyntaxError) End Using End Function @@ -612,8 +615,9 @@ End Class Dim result = Await AnalyzeDocumentAsync(oldProject, newSolution.GetDocument(documentId)) ' no declaration errors (error in method body is only reported when emitting) - Assert.False(result.HasChangesAndErrors) - Assert.False(result.HasChangesAndSyntaxErrors) + Assert.False(result.AnalysisBlocked) + Assert.False(result.HasBlockingRudeEdits) + Assert.Null(result.SyntaxError) End Using End Function @@ -645,8 +649,9 @@ End Class ' No errors reported: EnC analyzer is resilient against semantic errors. ' They will be reported by 1) compiler diagnostic analyzer 2) when emitting delta - if still present. - Assert.False(result.HasChangesAndErrors) - Assert.False(result.HasChangesAndSyntaxErrors) + Assert.False(result.AnalysisBlocked) + Assert.False(result.HasBlockingRudeEdits) + Assert.Null(result.SyntaxError) End Using End Function diff --git a/src/roslyn/src/Features/VisualBasicTest/ImplementInterface/ImplementInterfaceCodeRefactoringTests.vb b/src/roslyn/src/Features/VisualBasicTest/ImplementInterface/ImplementInterfaceCodeRefactoringTests.vb new file mode 100644 index 00000000000..6d26e13134e --- /dev/null +++ b/src/roslyn/src/Features/VisualBasicTest/ImplementInterface/ImplementInterfaceCodeRefactoringTests.vb @@ -0,0 +1,55 @@ +' Licensed to the .NET Foundation under one or more agreements. +' The .NET Foundation licenses this file to you under the MIT license. +' See the LICENSE file in the project root for more information. + +Imports VerifyVb = Microsoft.CodeAnalysis.Editor.UnitTests.CodeActions.VisualBasicCodeRefactoringVerifier(Of + Microsoft.CodeAnalysis.ImplementInterface.ImplementInterfaceCodeRefactoringProvider) + +Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.ImplementInterface + + + Public NotInheritable Class ImplementInterfaceCodeRefactoringTests + + + Public Function TestInBody() As Task + Return VerifyVb.VerifyRefactoringAsync(" +interface IGoo + sub Goo() +end interface + +class C + implements {|BC30149:IGoo|} + + $$ +end class + ", " +interface IGoo + sub Goo() +end interface + +class C + implements IGoo + + Public Sub Goo() Implements IGoo.Goo + Throw New System.NotImplementedException() + End Sub +end class + ") + End Function + + + Public Function TestNotOnInterfaceInBody() As Task + Return VerifyVb.VerifyRefactoringAsync(" +interface IGoo + sub Goo() +end interface + +interface IBar + inherits IGoo + + $$ +end interface + ") + End Function + End Class +End Namespace diff --git a/src/roslyn/src/Interactive/HostTest/AbstractInteractiveHostTests.cs b/src/roslyn/src/Interactive/HostTest/AbstractInteractiveHostTests.cs index a733de3dad0..ea9e007039d 100644 --- a/src/roslyn/src/Interactive/HostTest/AbstractInteractiveHostTests.cs +++ b/src/roslyn/src/Interactive/HostTest/AbstractInteractiveHostTests.cs @@ -22,6 +22,7 @@ namespace Microsoft.CodeAnalysis.UnitTests.Interactive { using InteractiveHost::Microsoft.CodeAnalysis.Interactive; + using Xunit.Abstractions; public abstract class AbstractInteractiveHostTests : CSharpTestBase, IAsyncLifetime { @@ -30,6 +31,7 @@ public abstract class AbstractInteractiveHostTests : CSharpTestBase, IAsyncLifet private int[] _outputReadPosition = [0, 0]; internal readonly InteractiveHost Host; + internal readonly ITestOutputHelper TestOutputHelper; // DOTNET_ROOT must be set in order to run host process on .NET Core on machines (like CI) // that do not have the required version of the runtime installed globally. @@ -57,12 +59,13 @@ static AbstractInteractiveHostTests() } } - protected AbstractInteractiveHostTests() + protected AbstractInteractiveHostTests(ITestOutputHelper testOutputHelper) { + TestOutputHelper = testOutputHelper; Host = new InteractiveHost(typeof(CSharpReplServiceProvider), ".", millisecondsTimeout: -1, joinOutputWritingThreadsOnDisposal: true); Host.InteractiveHostProcessCreationFailed += (exception, exitCode) => - Assert.False(true, (exception?.Message ?? "Host process terminated unexpectedly.") + $" Exit code: {exitCode?.ToString() ?? ""}"); + testOutputHelper.WriteLine((exception?.Message ?? "Host process terminated unexpectedly.") + $" Exit code: {exitCode?.ToString() ?? ""}"); RedirectOutput(); } diff --git a/src/roslyn/src/Interactive/HostTest/InteractiveHostCoreInitTests.cs b/src/roslyn/src/Interactive/HostTest/InteractiveHostCoreInitTests.cs index 6dff687d2e2..a635abd68b5 100644 --- a/src/roslyn/src/Interactive/HostTest/InteractiveHostCoreInitTests.cs +++ b/src/roslyn/src/Interactive/HostTest/InteractiveHostCoreInitTests.cs @@ -14,9 +14,10 @@ namespace Microsoft.CodeAnalysis.UnitTests.Interactive { using InteractiveHost::Microsoft.CodeAnalysis.Interactive; + using Xunit.Abstractions; [Trait(Traits.Feature, Traits.Features.InteractiveHost)] - public sealed class InteractiveHostCoreInitTests : AbstractInteractiveHostTests + public sealed class InteractiveHostCoreInitTests(ITestOutputHelper testOutputHelper) : AbstractInteractiveHostTests(testOutputHelper) { internal override InteractiveHostPlatform DefaultPlatform => InteractiveHostPlatform.Core; internal override bool UseDefaultInitializationFile => true; diff --git a/src/roslyn/src/Interactive/HostTest/InteractiveHostCoreTests.cs b/src/roslyn/src/Interactive/HostTest/InteractiveHostCoreTests.cs index 39a0bc1148f..4ca3b11379e 100644 --- a/src/roslyn/src/Interactive/HostTest/InteractiveHostCoreTests.cs +++ b/src/roslyn/src/Interactive/HostTest/InteractiveHostCoreTests.cs @@ -10,9 +10,10 @@ namespace Microsoft.CodeAnalysis.UnitTests.Interactive { using InteractiveHost::Microsoft.CodeAnalysis.Interactive; + using Xunit.Abstractions; [Trait(Traits.Feature, Traits.Features.InteractiveHost)] - public sealed class InteractiveHostCoreTests : AbstractInteractiveHostTests + public sealed class InteractiveHostCoreTests(ITestOutputHelper testOutputHelper) : AbstractInteractiveHostTests(testOutputHelper) { internal override InteractiveHostPlatform DefaultPlatform => InteractiveHostPlatform.Core; internal override bool UseDefaultInitializationFile => false; diff --git a/src/roslyn/src/Interactive/HostTest/InteractiveHostDesktopInitTests.cs b/src/roslyn/src/Interactive/HostTest/InteractiveHostDesktopInitTests.cs index 3db92fbef3a..7749771c81c 100644 --- a/src/roslyn/src/Interactive/HostTest/InteractiveHostDesktopInitTests.cs +++ b/src/roslyn/src/Interactive/HostTest/InteractiveHostDesktopInitTests.cs @@ -13,9 +13,10 @@ namespace Microsoft.CodeAnalysis.UnitTests.Interactive { using InteractiveHost::Microsoft.CodeAnalysis.Interactive; + using Xunit.Abstractions; [Trait(Traits.Feature, Traits.Features.InteractiveHost)] - public sealed class InteractiveHostDesktopInitTests : AbstractInteractiveHostTests + public sealed class InteractiveHostDesktopInitTests(ITestOutputHelper testOutputHelper) : AbstractInteractiveHostTests(testOutputHelper) { internal override InteractiveHostPlatform DefaultPlatform => InteractiveHostPlatform.Desktop32; internal override bool UseDefaultInitializationFile => true; diff --git a/src/roslyn/src/Interactive/HostTest/InteractiveHostDesktopTests.cs b/src/roslyn/src/Interactive/HostTest/InteractiveHostDesktopTests.cs index eda6c32516d..e25a04752fe 100644 --- a/src/roslyn/src/Interactive/HostTest/InteractiveHostDesktopTests.cs +++ b/src/roslyn/src/Interactive/HostTest/InteractiveHostDesktopTests.cs @@ -18,9 +18,10 @@ namespace Microsoft.CodeAnalysis.UnitTests.Interactive { using InteractiveHost::Microsoft.CodeAnalysis.Interactive; + using Xunit.Abstractions; [Trait(Traits.Feature, Traits.Features.InteractiveHost)] - public sealed class InteractiveHostDesktopTests : AbstractInteractiveHostTests + public sealed class InteractiveHostDesktopTests(ITestOutputHelper testOutputHelper) : AbstractInteractiveHostTests(testOutputHelper) { internal override InteractiveHostPlatform DefaultPlatform => InteractiveHostPlatform.Desktop64; internal override bool UseDefaultInitializationFile => false; diff --git a/src/roslyn/src/LanguageServer/Protocol/Workspaces/LspWorkspaceRegistrationService.cs b/src/roslyn/src/LanguageServer/Protocol/Workspaces/LspWorkspaceRegistrationService.cs index 35f3406c1bb..1b7a230ddb6 100644 --- a/src/roslyn/src/LanguageServer/Protocol/Workspaces/LspWorkspaceRegistrationService.cs +++ b/src/roslyn/src/LanguageServer/Protocol/Workspaces/LspWorkspaceRegistrationService.cs @@ -39,7 +39,9 @@ public virtual void Register(Workspace? workspace) m["WorkspacePartialSemanticsEnabled"] = workspace.PartialSemanticsEnabled; }, workspace)); - var workspaceChangedDisposer = workspace.RegisterWorkspaceChangedHandler(OnLspWorkspaceChanged); + // Forward workspace change events for all registered LSP workspaces. Requires main thread as it + // fires LspSolutionChanged which hasn't been guaranteed to be thread safe. + var workspaceChangedDisposer = workspace.RegisterWorkspaceChangedHandler(OnLspWorkspaceChanged, WorkspaceEventOptions.RequiresMainThreadOptions); lock (_gate) { @@ -92,7 +94,9 @@ public void Dispose() } /// - /// Indicates whether the LSP solution has changed in a non-tracked document context. May be raised on any thread. + /// Indicates whether the LSP solution has changed in a non-tracked document context. + /// + /// IMPORTANT: Implementations of this event handler should do as little synchronous work as possible since this will block. /// public EventHandler? LspSolutionChanged; } diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsCSharpAsync_False/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsCSharpAsync_False/Resources.Designer.cs index c1c925afa5a..2fac9e79a91 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsCSharpAsync_False/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsCSharpAsync_False/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsCSharpAsync_True/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsCSharpAsync_True/Resources.Designer.cs index c7688ac134b..f73138317b9 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsCSharpAsync_True/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsCSharpAsync_True/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public const string @Name = "Name"; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsVisualBasicAsync_False/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsVisualBasicAsync_False/Resources.Designer.vb index 7e5e0abe937..1881b74aa2f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsVisualBasicAsync_False/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsVisualBasicAsync_False/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsVisualBasicAsync_True/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsVisualBasicAsync_True/Resources.Designer.vb index 3a7ff2a36a2..51007fe2741 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsVisualBasicAsync_True/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_AsConstantsVisualBasicAsync_True/Resources.Designer.vb @@ -26,4 +26,4 @@ Namespace Global.TestProject Public Const [Name] As String = "Name" End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync/Resources.Designer.cs index c1c925afa5a..2fac9e79a91 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync_NS/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync_NS/Resources.Designer.cs index 88c52285685..7e9c3d31869 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync_NS/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync_NS/Resources.Designer.cs @@ -20,4 +20,3 @@ internal static partial class NS public static string @Name => GetResourceString("Name")!; } - diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync_NS1.NS2/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync_NS1.NS2/Resources.Designer.cs index 4ded4b004c5..0b14582ae4d 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync_NS1.NS2/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameCSharpAsync_NS1.NS2/Resources.Designer.cs @@ -21,4 +21,4 @@ internal static partial class NS2 public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync/Resources.Designer.vb index 7e5e0abe937..1881b74aa2f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync_NS/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync_NS/Resources.Designer.vb index 84a8ca15a65..99fb93d5066 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync_NS/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync_NS/Resources.Designer.vb @@ -33,4 +33,3 @@ Friend Partial Class NS End Property End Class - diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync_NS1.NS2/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync_NS1.NS2/Resources.Designer.vb index 866c481c2e8..aec967ea7e6 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync_NS1.NS2/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_ClassNameVisualBasicAsync_NS1.NS2/Resources.Designer.vb @@ -33,4 +33,4 @@ Namespace Global.NS1 End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp5/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp5/Resources.Designer.cs index ff7d2796857..1add95c0120 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp5/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp5/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name"); } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp6/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp6/Resources.Designer.cs index ff7d2796857..1add95c0120 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp6/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp6/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name"); } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp7/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp7/Resources.Designer.cs index ff7d2796857..1add95c0120 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp7/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp7/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name"); } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp8/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp8/Resources.Designer.cs index c1c925afa5a..2fac9e79a91 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp8/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp8/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp9/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp9/Resources.Designer.cs index c1c925afa5a..2fac9e79a91 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp9/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultCSharpAsync_CSharp9/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultVisualBasicAsync/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultVisualBasicAsync/Resources.Designer.vb index 7e5e0abe937..1881b74aa2f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultVisualBasicAsync/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_DefaultVisualBasicAsync/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_0_False/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_0_False/Resources.Designer.cs index 5d380b3db16..a3bf560ad79 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_0_False/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_0_False/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_0_True/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_0_True/Resources.Designer.cs index b3919a15c4f..12087eef572 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_0_True/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_0_True/Resources.Designer.cs @@ -14,7 +14,6 @@ internal static partial class Resources [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] [return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull("defaultValue")] internal static string? GetResourceString(string resourceKey, string? defaultValue = null) => ResourceManager.GetString(resourceKey, Culture) ?? defaultValue; - private static string GetResourceString(string resourceKey, string[]? formatterNames) { var value = GetResourceString(resourceKey) ?? ""; @@ -27,7 +26,6 @@ private static string GetResourceString(string resourceKey, string[]? formatterN } return value; } - /// value {0} public static string @Name => GetResourceString("Name")!; /// value {0} @@ -36,4 +34,4 @@ internal static string FormatName(object? p0) } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_replacement_False/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_replacement_False/Resources.Designer.cs index 4feef75d44d..590417cc803 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_replacement_False/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_replacement_False/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_replacement_True/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_replacement_True/Resources.Designer.cs index fa77240ec63..06520b226cd 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_replacement_True/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_replacement_True/Resources.Designer.cs @@ -14,7 +14,6 @@ internal static partial class Resources [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] [return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull("defaultValue")] internal static string? GetResourceString(string resourceKey, string? defaultValue = null) => ResourceManager.GetString(resourceKey, Culture) ?? defaultValue; - private static string GetResourceString(string resourceKey, string[]? formatterNames) { var value = GetResourceString(resourceKey) ?? ""; @@ -27,7 +26,6 @@ private static string GetResourceString(string resourceKey, string[]? formatterN } return value; } - /// value {replacement} public static string @Name => GetResourceString("Name")!; /// value {replacement} @@ -36,4 +34,4 @@ internal static string FormatName(object? replacement) } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_x_False/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_x_False/Resources.Designer.cs index 19b20ba8116..2587512dce4 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_x_False/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_x_False/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_x_True/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_x_True/Resources.Designer.cs index fe057e9cbfc..a7f8f5585ef 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_x_True/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsCSharpAsync_x_True/Resources.Designer.cs @@ -14,7 +14,6 @@ internal static partial class Resources [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)] [return: global::System.Diagnostics.CodeAnalysis.NotNullIfNotNull("defaultValue")] internal static string? GetResourceString(string resourceKey, string? defaultValue = null) => ResourceManager.GetString(resourceKey, Culture) ?? defaultValue; - private static string GetResourceString(string resourceKey, string[]? formatterNames) { var value = GetResourceString(resourceKey) ?? ""; @@ -27,7 +26,6 @@ private static string GetResourceString(string resourceKey, string[]? formatterN } return value; } - /// value {x} public static string @Name => GetResourceString("Name")!; /// value {x} @@ -36,4 +34,4 @@ internal static string FormatName(object? x) } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsVisualBasicAsync_False/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsVisualBasicAsync_False/Resources.Designer.vb index 7e5e0abe937..1881b74aa2f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsVisualBasicAsync_False/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_EmitFormatMethodsVisualBasicAsync_False/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesCSharpAsync_False/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesCSharpAsync_False/Resources.Designer.cs index c1c925afa5a..2fac9e79a91 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesCSharpAsync_False/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesCSharpAsync_False/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesCSharpAsync_True/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesCSharpAsync_True/Resources.Designer.cs index 1473a8f809b..63a7569d3f4 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesCSharpAsync_True/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesCSharpAsync_True/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name", @"value"); } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesVisualBasicAsync_False/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesVisualBasicAsync_False/Resources.Designer.vb index 7e5e0abe937..1881b74aa2f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesVisualBasicAsync_False/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesVisualBasicAsync_False/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesVisualBasicAsync_True/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesVisualBasicAsync_True/Resources.Designer.vb index a7d121e8de9..efd9799c93b 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesVisualBasicAsync_True/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_IncludeDefaultValuesVisualBasicAsync_True/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync/Resources.Designer.cs index c1c925afa5a..2fac9e79a91 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync_CS1591/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync_CS1591/Resources.Designer.cs index 2de335ef912..18d0d80d628 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync_CS1591/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync_CS1591/Resources.Designer.cs @@ -22,4 +22,4 @@ internal static partial class Resources } } -#pragma warning restore CS1591 +#pragma warning restore CS1591 \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync_CS1591_IDE0010/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync_CS1591_IDE0010/Resources.Designer.cs index 62cee7c3c5d..0d2a9ee2c9c 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync_CS1591_IDE0010/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsCSharpAsync_CS1591_IDE0010/Resources.Designer.cs @@ -22,4 +22,4 @@ internal static partial class Resources } } -#pragma warning restore CS1591, IDE0010 +#pragma warning restore CS1591, IDE0010 \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync/Resources.Designer.vb index 7e5e0abe937..1881b74aa2f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync_CS1591/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync_CS1591/Resources.Designer.vb index 17132d5e682..d6bc23deb51 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync_CS1591/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync_CS1591/Resources.Designer.vb @@ -34,4 +34,4 @@ Namespace Global.TestProject End Class End Namespace -#Enable Warning CS1591 +#Enable Warning CS1591 \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync_CS1591_IDE0010/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync_CS1591_IDE0010/Resources.Designer.vb index 72d82353a18..13a14784266 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync_CS1591_IDE0010/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_NoWarnsVisualBasicAsync_CS1591_IDE0010/Resources.Designer.vb @@ -34,4 +34,4 @@ Namespace Global.TestProject End Class End Namespace -#Enable Warning CS1591, IDE0010 +#Enable Warning CS1591, IDE0010 \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringCSharpAsync_False/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringCSharpAsync_False/Resources.Designer.cs index c1c925afa5a..2fac9e79a91 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringCSharpAsync_False/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringCSharpAsync_False/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringCSharpAsync_True/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringCSharpAsync_True/Resources.Designer.cs index 82e188c9794..4dcdb8ee2d7 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringCSharpAsync_True/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringCSharpAsync_True/Resources.Designer.cs @@ -15,4 +15,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringVisualBasicAsync_False/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringVisualBasicAsync_False/Resources.Designer.vb index 7e5e0abe937..1881b74aa2f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringVisualBasicAsync_False/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringVisualBasicAsync_False/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringVisualBasicAsync_True/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringVisualBasicAsync_True/Resources.Designer.vb index 2a310c4b2fc..e09b6fa5270 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringVisualBasicAsync_True/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_OmitGetResourceStringVisualBasicAsync_True/Resources.Designer.vb @@ -26,4 +26,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicCSharpAsync_False/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicCSharpAsync_False/Resources.Designer.cs index c1c925afa5a..2fac9e79a91 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicCSharpAsync_False/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicCSharpAsync_False/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicCSharpAsync_True/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicCSharpAsync_True/Resources.Designer.cs index 5aec8c10768..fa8c5ef10b5 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicCSharpAsync_True/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicCSharpAsync_True/Resources.Designer.cs @@ -18,4 +18,4 @@ public static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicVisualBasicAsync_False/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicVisualBasicAsync_False/Resources.Designer.vb index 7e5e0abe937..1881b74aa2f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicVisualBasicAsync_False/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicVisualBasicAsync_False/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicVisualBasicAsync_True/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicVisualBasicAsync_True/Resources.Designer.vb index 64be47f98a0..93940b29acd 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicVisualBasicAsync_True/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_PublicVisualBasicAsync_True/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync/Resources.Designer.cs index c1c925afa5a..2fac9e79a91 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync_NS/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync_NS/Resources.Designer.cs index 1f3c879f307..a6af5bd3745 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync_NS/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync_NS/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class NSResources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync_NS1.NS2/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync_NS1.NS2/Resources.Designer.cs index f32431e7877..c1d9e6b1313 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync_NS1.NS2/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirCSharpAsync_NS1.NS2/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class NS2Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync/Resources.Designer.vb index 7e5e0abe937..1881b74aa2f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync_NS/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync_NS/Resources.Designer.vb index 8bd90c0fae2..847700ea28f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync_NS/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync_NS/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync_NS1.NS2/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync_NS1.NS2/Resources.Designer.vb index c0a22ef9916..af17bb8acc0 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync_NS1.NS2/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RelativeDirVisualBasicAsync_NS1.NS2/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject.NS1 End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync/Resources.Designer.cs index f82cd001930..030e93a3845 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync/Resources.Designer.cs @@ -17,4 +17,3 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } - diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync_NS/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync_NS/Resources.Designer.cs index e92f3ef2ade..a843b814f1f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync_NS/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync_NS/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync_NS1.NS2/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync_NS1.NS2/Resources.Designer.cs index 9bdce5dfefd..523f57c6448 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync_NS1.NS2/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceCSharpAsync_NS1.NS2/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync/Resources.Designer.vb index 0b157c51018..9359a0d0fa1 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync/Resources.Designer.vb @@ -30,4 +30,3 @@ Friend Partial Class Resources End Property End Class - diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync_NS/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync_NS/Resources.Designer.vb index 1d7d203bc1f..ca6eedd3ab0 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync_NS/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync_NS/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.NS End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync_NS1.NS2/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync_NS1.NS2/Resources.Designer.vb index 25ea9cf6a93..8e004bd0a81 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync_NS1.NS2/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/SingleString_RootNamespaceVisualBasicAsync_NS1.NS2/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.NS1.NS2 End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultCSharpAsync/Resources.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultCSharpAsync/Resources.Designer.cs index ec47ea64240..6074150a4e4 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultCSharpAsync/Resources.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultCSharpAsync/Resources.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultCSharpAsync/Resources0.Designer.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultCSharpAsync/Resources0.Designer.cs index 26e3d38af15..35ec698372f 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultCSharpAsync/Resources0.Designer.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultCSharpAsync/Resources0.Designer.cs @@ -18,4 +18,4 @@ internal static partial class Resources public static string @Name => GetResourceString("Name")!; } -} +} \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultVisualBasicAsync/Resources.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultVisualBasicAsync/Resources.Designer.vb index dd7fa8fdeb5..24298d6b5a7 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultVisualBasicAsync/Resources.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultVisualBasicAsync/Resources.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject.First End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultVisualBasicAsync/Resources0.Designer.vb b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultVisualBasicAsync/Resources0.Designer.vb index b4a921a70e1..2bc55392ba0 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultVisualBasicAsync/Resources0.Designer.vb +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator.UnitTests/Resources/TwoResourcesSameName_DefaultVisualBasicAsync/Resources0.Designer.vb @@ -30,4 +30,4 @@ Namespace Global.TestProject.Second End Property End Class -End Namespace +End Namespace \ No newline at end of file diff --git a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator/AbstractResxGenerator.cs b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator/AbstractResxGenerator.cs index dfa509b9a44..1d9bb6027c9 100644 --- a/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator/AbstractResxGenerator.cs +++ b/src/roslyn/src/RoslynAnalyzers/Microsoft.CodeAnalysis.ResxSourceGenerator/Microsoft.CodeAnalysis.ResxSourceGenerator/AbstractResxGenerator.cs @@ -519,6 +519,7 @@ public bool Execute(CancellationToken cancellationToken) if (ResourceInformation.EmitFormatMethods) { getStringMethod += $$""" + {{memberIndent}}private static string GetResourceString(string resourceKey, string[]? formatterNames) {{memberIndent}}{ {{memberIndent}} var value = GetResourceString(resourceKey) ?? ""; diff --git a/src/roslyn/src/RoslynAnalyzers/Utilities.UnitTests/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysisTests.cs b/src/roslyn/src/RoslynAnalyzers/Utilities.UnitTests/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysisTests.cs index a512fd506f5..434026e4ce0 100644 --- a/src/roslyn/src/RoslynAnalyzers/Utilities.UnitTests/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysisTests.cs +++ b/src/roslyn/src/RoslynAnalyzers/Utilities.UnitTests/FlowAnalysis/Analysis/PropertySetAnalysis/PropertySetAnalysisTests.cs @@ -163,54 +163,53 @@ static string MethodOrReturnString(string? method) } } - private readonly string TestTypeToTrackSource = """ - public class TestTypeToTrack - { - public TestEnum AnEnum { get; set; } - public object AnObject { get; set; } - public string AString { get; set; } + private readonly string TestTypeToTrackSource = @" +public class TestTypeToTrack +{ + public TestEnum AnEnum { get; set; } + public object AnObject { get; set; } + public string AString { get; set; } - public void Method() - { - } - } + public void Method() + { + } +} - public class TestTypeToTrackWithConstructor : TestTypeToTrack - { - private TestTypeToTrackWithConstructor() - { - } +public class TestTypeToTrackWithConstructor : TestTypeToTrack +{ + private TestTypeToTrackWithConstructor() + { + } - public TestTypeToTrackWithConstructor(TestEnum enu, object obj, string str) - { - this.AnEnum = enu; - this.AnObject = obj; - this.AString = str; - } - } + public TestTypeToTrackWithConstructor(TestEnum enu, object obj, string str) + { + this.AnEnum = enu; + this.AnObject = obj; + this.AString = str; + } +} - public enum TestEnum - { - Value0, - Value1, - Value2, - } +public enum TestEnum +{ + Value0, + Value1, + Value2, +} - public class OtherClass - { - public void OtherMethod(TestTypeToTrack t) - { - } +public class OtherClass +{ + public void OtherMethod(TestTypeToTrack t) + { + } - public void OtherMethod(string s, TestTypeToTrack t) - { - } + public void OtherMethod(string s, TestTypeToTrack t) + { + } - public static void StaticMethod(TestTypeToTrack staticMethodParameter) - { - } - } - """; + public static void StaticMethod(TestTypeToTrack staticMethodParameter) + { + } +}"; /// /// Parameters for PropertySetAnalysis to flag hazardous usage when the TestTypeToTrack.AString property is not null @@ -288,17 +287,16 @@ public static void StaticMethod(TestTypeToTrack staticMethodParameter) [Fact] public void TestTypeToTrack_HazardousIfStringIsNonNull_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = "A non-null string"; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = ""A non-null string""; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringIsNonNull, (8, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -306,19 +304,18 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringIsNonNull_StringEmpty_Flagged() { - VerifyCSharp(""" - using System; + VerifyCSharp(@" +using System; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = String.Empty; - t.Method(); - }/**/ - } - """, +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = String.Empty; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringIsNonNull, (10, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -326,35 +323,33 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringIsNonNull_Unflagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = null; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = null; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringIsNonNull); } [Fact] public void TestTypeToTrack_HazardousIfStringIsNull_OtherMethod_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = "A non-null string"; - OtherClass o = new OtherClass(); - o.OtherMethod("this string parameter is ignored", t); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = ""A non-null string""; + OtherClass o = new OtherClass(); + o.OtherMethod(""this string parameter is ignored"", t); + }/**/ +}", TestTypeToTrack_HazardousIfStringIsNonNull, (9, 9, "void OtherClass.OtherMethod(string s, TestTypeToTrack t)", HazardousUsageEvaluationResult.Flagged)); } @@ -362,17 +357,16 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringIsNull_StaticMethod_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = "A non-null string"; - OtherClass.StaticMethod(t); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = ""A non-null string""; + OtherClass.StaticMethod(t); + }/**/ +}", TestTypeToTrack_HazardousIfStringIsNonNull, (8, 9, "void OtherClass.StaticMethod(TestTypeToTrack staticMethodParameter)", HazardousUsageEvaluationResult.Flagged)); } @@ -380,19 +374,18 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringIsNull_OtherClassBothMethods_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = "A non-null string"; - OtherClass o = new OtherClass(); - o.OtherMethod("this string parameter is ignored", t); - OtherClass.StaticMethod(t); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = ""A non-null string""; + OtherClass o = new OtherClass(); + o.OtherMethod(""this string parameter is ignored"", t); + OtherClass.StaticMethod(t); + }/**/ +}", TestTypeToTrack_HazardousIfStringIsNonNull, (9, 9, "void OtherClass.OtherMethod(string s, TestTypeToTrack t)", HazardousUsageEvaluationResult.Flagged), (10, 9, "void OtherClass.StaticMethod(TestTypeToTrack staticMethodParameter)", HazardousUsageEvaluationResult.Flagged)); @@ -456,16 +449,15 @@ void TestMethod() [Fact] public void TestTypeToTrackWithConstructor_HazardousIfStringIsNull_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, "A non-null string"); - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, ""A non-null string""); + t.Method(); + }/**/ +}", TestTypeToTrackWithConstructor_HazardousIfStringIsNonNull, (7, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -473,18 +465,17 @@ void TestMethod() [Fact] public void TestTypeToTrackWithConstructor_HazardousIfStringIsNull_StringEmpty_Flagged() { - VerifyCSharp(""" - using System; + VerifyCSharp(@" +using System; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, String.Empty); - t.Method(); - }/**/ - } - """, +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, String.Empty); + t.Method(); + }/**/ +}", TestTypeToTrackWithConstructor_HazardousIfStringIsNonNull, (9, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -492,33 +483,31 @@ void TestMethod() [Fact] public void TestTypeToTrackWithConstructor_HazardousIfStringIsNull_Unflagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, null); - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, null); + t.Method(); + }/**/ +}", TestTypeToTrackWithConstructor_HazardousIfStringIsNonNull); } [Fact] public void TestTypeToTrackWithConstructor_HazardousIfStringIsNull_PropertyAssigned_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, null); - t.AString = ""; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, null); + t.AString = """"; + t.Method(); + }/**/ +}", TestTypeToTrackWithConstructor_HazardousIfStringIsNonNull, (8, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -559,17 +548,16 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfEnumIsValue0_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AnEnum = TestEnum.Value0; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AnEnum = TestEnum.Value0; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfEnumIsValue0, (8, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -577,17 +565,16 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfEnumIsValue0_Unflagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AnEnum = TestEnum.Value2; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AnEnum = TestEnum.Value2; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfEnumIsValue0); } @@ -634,32 +621,30 @@ void TestMethod() [Fact] public void TestTypeToTrackWithConstructor_HazardousIfEnumIsValue0_Unflagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(TestEnum.Value2, null, null); - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(TestEnum.Value2, null, null); + t.Method(); + }/**/ +}", TestTypeToTrackWithConstructor_HazardousIfEnumIsValue0); } [Fact] public void TestTypeToTrackWithConstructor_HazardousIfEnumIsValue0_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(TestEnum.Value0, null, null); - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(TestEnum.Value0, null, null); + t.Method(); + }/**/ +}", TestTypeToTrackWithConstructor_HazardousIfEnumIsValue0, (7, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -718,18 +703,17 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringStartsWithTAndValue2_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = "The beginning of knowledge is the discovery of something we do not understand."; - t.AnEnum = TestEnum.Value2; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = ""The beginning of knowledge is the discovery of something we do not understand.""; + t.AnEnum = TestEnum.Value2; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringStartsWithTAndValue2, (9, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -737,30 +721,29 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringStartsWithTAndValue2_BothMaybe_MaybeFlagged() { - VerifyCSharp(""" - using System; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - Random r = new Random(); - t.AString = "T"; - t.AnEnum = TestEnum.Value2; - if (r.Next(6) == 4) - { - t.AString = "A different string."; - } + VerifyCSharp(@" +using System; +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + Random r = new Random(); + t.AString = ""T""; + t.AnEnum = TestEnum.Value2; + if (r.Next(6) == 4) + { + t.AString = ""A different string.""; + } - if (r.Next(6) == 4) - { - t.AnEnum = TestEnum.Value1; - } + if (r.Next(6) == 4) + { + t.AnEnum = TestEnum.Value1; + } - t.Method(); - }/**/ - } - """, + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringStartsWithTAndValue2, (21, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.MaybeFlagged)); } @@ -768,25 +751,24 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringStartsWithTAndValue2_FirstMaybe_MaybeFlagged() { - VerifyCSharp(""" - using System; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - Random r = new Random(); - t.AString = "T"; - t.AnEnum = TestEnum.Value2; - if (r.Next(6) == 4) - { - t.AString = "A different string."; - } + VerifyCSharp(@" +using System; +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + Random r = new Random(); + t.AString = ""T""; + t.AnEnum = TestEnum.Value2; + if (r.Next(6) == 4) + { + t.AString = ""A different string.""; + } - t.Method(); - }/**/ - } - """, + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringStartsWithTAndValue2, (16, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.MaybeFlagged)); } @@ -794,25 +776,24 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringStartsWithTAndValue2_SecondMaybe_MaybeFlagged() { - VerifyCSharp(""" - using System; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - Random r = new Random(); - t.AString = "T"; - t.AnEnum = TestEnum.Value2; - if (r.Next(6) == 4) - { - t.AnEnum = TestEnum.Value1; - } + VerifyCSharp(@" +using System; +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + Random r = new Random(); + t.AString = ""T""; + t.AnEnum = TestEnum.Value2; + if (r.Next(6) == 4) + { + t.AnEnum = TestEnum.Value1; + } - t.Method(); - }/**/ - } - """, + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringStartsWithTAndValue2, (16, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.MaybeFlagged)); } @@ -820,19 +801,18 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringStartsWithTAndValue2_FirstFlagged_Unflagged() { - VerifyCSharp(""" - using System; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - Random r = new Random(); - t.AString = "T"; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +using System; +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + Random r = new Random(); + t.AString = ""T""; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringStartsWithTAndValue2); } @@ -901,19 +881,18 @@ void TestMethod() [Fact] public void TestTypeToTrackWithConstructor_HazardousIfObjectIsBitArray_Constructor_Flagged() { - VerifyCSharp(""" - using System; - using System.Collections; + VerifyCSharp(@" +using System; +using System.Collections; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), new BitArray(4), "string"); - t.Method(); - }/**/ - } - """, +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), new BitArray(4), ""string""); + t.Method(); + }/**/ +}", TestTypeToTrackWithConstructor_HazardousIfObjectIsBitArray, (10, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -921,23 +900,22 @@ void TestMethod() [Fact] public void TestTypeToTrackWithConstructor_HazardousIfObjectIsBitArray_Constructor_TwoPaths_Flagged() { - VerifyCSharp(""" - using System; - using System.Collections; + VerifyCSharp(@" +using System; +using System.Collections; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t; - if (new Random().Next(6) == 4) - t = new TestTypeToTrackWithConstructor(default(TestEnum), new BitArray(6), "string"); - else - t = new TestTypeToTrackWithConstructor(default(TestEnum), "object string", "string"); - t.Method(); // PropertySetAnalysis is aggressive--at least one previous code path being Flagged means it's Flagged at this point. - }/**/ - } - """, +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t; + if (new Random().Next(6) == 4) + t = new TestTypeToTrackWithConstructor(default(TestEnum), new BitArray(6), ""string""); + else + t = new TestTypeToTrackWithConstructor(default(TestEnum), ""object string"", ""string""); + t.Method(); // PropertySetAnalysis is aggressive--at least one previous code path being Flagged means it's Flagged at this point. + }/**/ +}", TestTypeToTrackWithConstructor_HazardousIfObjectIsBitArray, (14, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -945,19 +923,18 @@ void TestMethod() [Fact] public void TestTypeToTrackWithConstructor_HazardousIfObjectIsBitArray_Constructor_NotFlagged() { - VerifyCSharp(""" - using System; - using System.Collections; + VerifyCSharp(@" +using System; +using System.Collections; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, "string"); - t.Method(); - }/**/ - } - """, +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, ""string""); + t.Method(); + }/**/ +}", TestTypeToTrackWithConstructor_HazardousIfObjectIsBitArray); } @@ -1008,19 +985,18 @@ void TestMethod() [Fact] public void TestTypeToTrackWithConstructor_HazardousIfAStringStartsWithA_Flagged() { - VerifyCSharp(""" - using System; - using System.Collections; + VerifyCSharp(@" +using System; +using System.Collections; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, "A string"); - t.Method(); - }/**/ - } - """, +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t = new TestTypeToTrackWithConstructor(default(TestEnum), null, ""A string""); + t.Method(); + }/**/ +}", TestTypeToTrackWithConstructor_HazardousIfAStringStartsWithA, (10, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -1028,24 +1004,23 @@ void TestMethod() [Fact] public void TestTypeToTrackWithConstructor_HazardousIfAStringStartsWithA_Interprocedural_Flagged() { - VerifyCSharp(""" - using System; - using System.Collections; + VerifyCSharp(@" +using System; +using System.Collections; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrackWithConstructor t = GetTestType(); - t.Method(); - }/**/ +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrackWithConstructor t = GetTestType(); + t.Method(); + }/**/ - TestTypeToTrackWithConstructor GetTestType() - { - return new TestTypeToTrackWithConstructor(default(TestEnum), null, "A string"); - } - } - """, + TestTypeToTrackWithConstructor GetTestType() + { + return new TestTypeToTrackWithConstructor(default(TestEnum), null, ""A string""); + } +}", TestTypeToTrackWithConstructor_HazardousIfAStringStartsWithA, (10, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -1090,17 +1065,16 @@ TestTypeToTrackWithConstructor GetTestType() [Fact] public void TestTypeToTrack_HazardousIfStringIsNonNullOnReturn_Flagged() { - VerifyCSharp(""" - class TestClass - { - TestTypeToTrack TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = "A non-null string"; - return t; - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + TestTypeToTrack TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = ""A non-null string""; + return t; + }/**/ +}", TestTypeToTrack_HazardousIfStringIsNonNullOnReturn, (8, 16, null, HazardousUsageEvaluationResult.Flagged)); } @@ -1108,18 +1082,17 @@ TestTypeToTrack TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringIsNonNullOnReturn_StringEmpty_Flagged() { - VerifyCSharp(""" - using System; - class TestClass - { - TestTypeToTrack TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = String.Empty; - return t; - }/**/ - } - """, + VerifyCSharp(@" +using System; +class TestClass +{ + TestTypeToTrack TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = String.Empty; + return t; + }/**/ +}", TestTypeToTrack_HazardousIfStringIsNonNullOnReturn, (9, 16, null, HazardousUsageEvaluationResult.Flagged)); } @@ -1127,34 +1100,32 @@ TestTypeToTrack TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringIsNonNullOnReturns_Unflagged() { - VerifyCSharp(""" - class TestClass - { - TestTypeToTrack TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = null; - return t; - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + TestTypeToTrack TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = null; + return t; + }/**/ +}", TestTypeToTrack_HazardousIfStringIsNonNullOnReturn); } [Fact] public void TestTypeToTrack_HazardousIfStringIsNonNullOnReturns_ReturnObject_Unflagged() { - VerifyCSharp(""" - class TestClass - { - object TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = "A non-null string"; - return new object(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + object TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = ""A non-null string""; + return new object(); + }/**/ +}", TestTypeToTrack_HazardousIfStringIsNonNullOnReturn); } @@ -1214,17 +1185,16 @@ object TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringObjectIsNonNull_AStringNonNull_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = "A non-null string"; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = ""A non-null string""; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringObjectIsNonNull, (8, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -1232,17 +1202,16 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringObjectIsNonNull_AnObjectNonNull_Flagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AnObject = new System.Random(); - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AnObject = new System.Random(); + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringObjectIsNonNull, (8, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -1250,18 +1219,17 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringObjectIsNonNull_StringEmpty_Flagged() { - VerifyCSharp(""" - using System; - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = String.Empty; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +using System; +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = String.Empty; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringObjectIsNonNull, (9, 9, "void TestTypeToTrack.Method()", HazardousUsageEvaluationResult.Flagged)); } @@ -1269,36 +1237,34 @@ void TestMethod() [Fact] public void TestTypeToTrack_HazardousIfStringObjectIsNonNull_StringNonNull_ObjectNull_Unflagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AString = "A non-null string"; - t.AnObject = null; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AString = ""A non-null string""; + t.AnObject = null; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringObjectIsNonNull); } [Fact] public void TestTypeToTrack_HazardousIfStringObjectIsNonNull_AnObjectNonNull_StringNull_Unflagged() { - VerifyCSharp(""" - class TestClass - { - void TestMethod() - /**/{ - TestTypeToTrack t = new TestTypeToTrack(); - t.AnObject = new System.Random(); - t.AString = null; - t.Method(); - }/**/ - } - """, + VerifyCSharp(@" +class TestClass +{ + void TestMethod() + /**/{ + TestTypeToTrack t = new TestTypeToTrack(); + t.AnObject = new System.Random(); + t.AString = null; + t.Method(); + }/**/ +}", TestTypeToTrack_HazardousIfStringObjectIsNonNull); } diff --git a/src/roslyn/src/Tools/ExternalAccess/RazorTest/RazorAnalyzerAssemblyResolverTests.cs b/src/roslyn/src/Tools/ExternalAccess/RazorTest/RazorAnalyzerAssemblyResolverTests.cs index d8d39eb32d1..7761f6faaab 100644 --- a/src/roslyn/src/Tools/ExternalAccess/RazorTest/RazorAnalyzerAssemblyResolverTests.cs +++ b/src/roslyn/src/Tools/ExternalAccess/RazorTest/RazorAnalyzerAssemblyResolverTests.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; using System.IO; using System.Linq; using System.Reflection; @@ -15,6 +16,8 @@ using Basic.Reference.Assemblies; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Utilities; +using Roslyn.Test.Utilities; using Xunit; namespace Microsoft.CodeAnalysis.ExternalAccess.Razor.UnitTests; @@ -22,11 +25,11 @@ namespace Microsoft.CodeAnalysis.ExternalAccess.Razor.UnitTests; public sealed class RazorAnalyzerAssemblyResolverTests : IDisposable { private TempRoot TempRoot { get; } = new TempRoot(); - private int InitialAssemblyCount { get; } + private ImmutableArray InitialAssemblies { get; } public RazorAnalyzerAssemblyResolverTests() { - InitialAssemblyCount = AssemblyLoadContext.GetLoadContext(this.GetType().Assembly)!.Assemblies.Count(); + InitialAssemblies = AssemblyLoadContext.GetLoadContext(this.GetType().Assembly)!.Assemblies.SelectAsArray(a => a.FullName); } public void Dispose() @@ -34,8 +37,8 @@ public void Dispose() TempRoot.Dispose(); // This test should not change the set of assemblies loaded in the current context. - var count = AssemblyLoadContext.GetLoadContext(this.GetType().Assembly)!.Assemblies.Count(); - Assert.Equal(InitialAssemblyCount, count); + var count = AssemblyLoadContext.GetLoadContext(this.GetType().Assembly)!.Assemblies.SelectAsArray(a => a.FullName); + AssertEx.SetEqual(InitialAssemblies, count); } private void CreateRazorAssemblies(string directory, string versionNumber = "1.0.0.0") @@ -93,7 +96,7 @@ private static void RunWithLoader(Action - [Fact] + [ConditionalFact(typeof(DesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/79352")] public void FallbackToCompilerContext() { var dir1 = TempRoot.CreateDirectory().Path; @@ -127,7 +130,7 @@ public void FallbackToCompilerContext() }); } - [Fact] + [ConditionalFact(typeof(DesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/79352")] public void FirstLoadWins() { var dir1 = TempRoot.CreateDirectory().Path; @@ -151,7 +154,7 @@ public void FirstLoadWins() }); } - [Fact] + [ConditionalFact(typeof(DesktopOnly), Reason = "https://github.com/dotnet/roslyn/issues/79352")] public void ChooseServiceHubFolder() { var dir = TempRoot.CreateDirectory().Path; diff --git a/src/roslyn/src/Tools/Source/RunTests/HelixTestRunner.cs b/src/roslyn/src/Tools/Source/RunTests/HelixTestRunner.cs index e1592f9a637..ddb9f8d9cdb 100644 --- a/src/roslyn/src/Tools/Source/RunTests/HelixTestRunner.cs +++ b/src/roslyn/src/Tools/Source/RunTests/HelixTestRunner.cs @@ -227,7 +227,7 @@ static void AppendHelixWorkItemProject( {workItemPayloadDir} {commandPrefix}{commandFileName} {commandPrefix}{postCommandFileName} - 00:30:00 + 01:00:00 {helixWorkItem.EstimatedExecutionTime} """); @@ -421,9 +421,15 @@ private static string GetRspFileContent( // The xml file must end in test-results.xml for the Azure Pipelines reporter to pick it up. builder.AppendLine($@"/Logger:xunit;LogFilePath=work-item-test-results.xml"); + // Also add a console logger so that the helix log reports results as we go. + builder.AppendLine($@"/Logger:console;verbosity=detailed"); + // Specifies the results directory - this is where dumps from the blame options will get published. builder.AppendLine($"/ResultsDirectory:."); + var blameOption = "CollectDump;CollectHangDump"; + builder.AppendLine($"/Blame:{blameOption};TestTimeout=15minutes;DumpType=full"); + // Build the filter string if (testMethodNames.Any()) { diff --git a/src/roslyn/src/VisualStudio/Core/Def/StackTraceExplorer/StackTraceExplorerViewModel.cs b/src/roslyn/src/VisualStudio/Core/Def/StackTraceExplorer/StackTraceExplorerViewModel.cs index 1c4c8e61664..3814232331d 100644 --- a/src/roslyn/src/VisualStudio/Core/Def/StackTraceExplorer/StackTraceExplorerViewModel.cs +++ b/src/roslyn/src/VisualStudio/Core/Def/StackTraceExplorer/StackTraceExplorerViewModel.cs @@ -50,6 +50,9 @@ public StackTraceExplorerViewModel(IThreadingContext threadingContext, Workspace _threadingContext = threadingContext; _workspace = workspace; + // Main thread dependency as Workspace_WorkspaceChanged modifies an ObservableCollection + _ = workspace.RegisterWorkspaceChangedHandler(Workspace_WorkspaceChanged, WorkspaceEventOptions.RequiresMainThreadOptions); + _classificationTypeMap = classificationTypeMap; _formatMap = formatMap; @@ -100,6 +103,15 @@ private void CallstackLines_CollectionChanged(object sender, System.Collections. NotifyPropertyChanged(nameof(IsInstructionTextVisible)); } + private void Workspace_WorkspaceChanged(WorkspaceChangeEventArgs e) + { + if (e.Kind == WorkspaceChangeKind.SolutionChanged) + { + Selection = null; + Frames.Clear(); + } + } + private FrameViewModel GetViewModel(ParsedFrame frame) => frame switch { diff --git a/src/roslyn/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/CpsDiagnosticItemSource.cs b/src/roslyn/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/CpsDiagnosticItemSource.cs index f5d797ba1df..0525b9c7cc1 100644 --- a/src/roslyn/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/CpsDiagnosticItemSource.cs +++ b/src/roslyn/src/VisualStudio/Core/Impl/SolutionExplorer/DiagnosticItem/CpsDiagnosticItemSource.cs @@ -19,7 +19,6 @@ internal sealed partial class CpsDiagnosticItemSource : BaseDiagnosticAndGenerat { private readonly IVsHierarchyItem _item; private readonly string _projectDirectoryPath; - private readonly string? _analyzerFilePath; private WorkspaceEventRegistration? _workspaceChangedDisposer; @@ -38,8 +37,6 @@ public CpsDiagnosticItemSource( _item = item; _projectDirectoryPath = Path.GetDirectoryName(projectPath); - _analyzerFilePath = CpsUtilities.ExtractAnalyzerFilePath(_projectDirectoryPath, _item.CanonicalName); - this.AnalyzerReference = TryGetAnalyzerReference(Workspace.CurrentSolution); if (this.AnalyzerReference == null) { @@ -50,7 +47,9 @@ public CpsDiagnosticItemSource( // then connect to it. if (workspace.CurrentSolution.ContainsProject(projectId)) { - _workspaceChangedDisposer = Workspace.RegisterWorkspaceChangedHandler(OnWorkspaceChangedLookForAnalyzer); + // Main thread dependency as OnWorkspaceChangedLookForAnalyzer accesses the IVsHierarchy + // and fires the PropertyChanged event + _workspaceChangedDisposer = Workspace.RegisterWorkspaceChangedHandler(OnWorkspaceChangedLookForAnalyzer, WorkspaceEventOptions.RequiresMainThreadOptions); item.PropertyChanged += IVsHierarchyItem_PropertyChanged; // Now that we've subscribed, check once more in case we missed the event @@ -119,11 +118,14 @@ private void OnWorkspaceChangedLookForAnalyzer(WorkspaceChangeEventArgs e) return null; } - if (string.IsNullOrEmpty(_analyzerFilePath)) + var canonicalName = _item.CanonicalName; + var analyzerFilePath = CpsUtilities.ExtractAnalyzerFilePath(_projectDirectoryPath, canonicalName); + + if (string.IsNullOrEmpty(analyzerFilePath)) { return null; } - return project.AnalyzerReferences.FirstOrDefault(r => string.Equals(r.FullPath, _analyzerFilePath, StringComparison.OrdinalIgnoreCase)); + return project.AnalyzerReferences.FirstOrDefault(r => string.Equals(r.FullPath, analyzerFilePath, StringComparison.OrdinalIgnoreCase)); } } diff --git a/src/roslyn/src/VisualStudio/ExternalAccess/Copilot/SemanticSearch/ISemanticSearchCopilotUIProviderImpl.cs b/src/roslyn/src/VisualStudio/ExternalAccess/Copilot/SemanticSearch/ISemanticSearchCopilotUIProviderImpl.cs deleted file mode 100644 index be636585901..00000000000 --- a/src/roslyn/src/VisualStudio/ExternalAccess/Copilot/SemanticSearch/ISemanticSearchCopilotUIProviderImpl.cs +++ /dev/null @@ -1,22 +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.Windows.Controls; -using Microsoft.VisualStudio.OLE.Interop; -using Microsoft.VisualStudio.Text.Editor; - -namespace Microsoft.CodeAnalysis.ExternalAccess.Copilot.SemanticSearch; - -internal interface ITextBoxControlImpl -{ - Control Control { get; } - string Text { get; set; } - IOleCommandTarget CommandTarget { get; } - IWpfTextView View { get; } -} - -internal interface ISemanticSearchCopilotUIProviderImpl -{ - ITextBoxControlImpl GetTextBox(); -} diff --git a/src/runtime/docs/workflow/requirements/macos-requirements.md b/src/runtime/docs/workflow/requirements/macos-requirements.md index 67e7840a64d..cd1aed4b8f1 100644 --- a/src/runtime/docs/workflow/requirements/macos-requirements.md +++ b/src/runtime/docs/workflow/requirements/macos-requirements.md @@ -18,7 +18,6 @@ To build the runtime repo, you will also need to install the following dependenc - `CMake` 3.20 or newer - `icu4c` -- `openssl@1.1` or `openssl@3` - `pkg-config` - `python3` - `ninja` (This one is optional. It is an alternative tool to `make` for building native code) diff --git a/src/runtime/eng/native/build-commons.sh b/src/runtime/eng/native/build-commons.sh index 2bc1faf27e7..a3bdc2ac190 100755 --- a/src/runtime/eng/native/build-commons.sh +++ b/src/runtime/eng/native/build-commons.sh @@ -70,7 +70,7 @@ build_native() # Let users provide additional compiler/linker flags via EXTRA_CFLAGS/EXTRA_CXXFLAGS/EXTRA_LDFLAGS. # If users directly override CFLAG/CXXFLAGS/LDFLAGS, that may lead to some configure tests working incorrectly. # See https://github.com/dotnet/runtime/issues/35727 for more information. - # + # # These flags MUST be exported before gen-buildsys.sh runs or cmake will ignore them # export CFLAGS="${CFLAGS} ${EXTRA_CFLAGS}" @@ -547,6 +547,9 @@ elif [[ "$__TargetOS" == ios || "$__TargetOS" == iossimulator ]]; then elif [[ "$__TargetOS" == tvos || "$__TargetOS" == tvossimulator ]]; then # nothing to do here true +elif [[ "$__TargetOS" == osx || "$__TargetOS" == maccatalyst ]]; then + # nothing to do here + true elif [[ "$__TargetOS" == android ]]; then # nothing to do here true diff --git a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml index 417241706c4..fa627d38ddd 100644 --- a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml +++ b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-android.yml @@ -76,7 +76,7 @@ jobs: nameSuffix: AllSubsets_Mono isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }} buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:EnableAdditionalTimezoneChecks=true - timeoutInMinutes: 480 + timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: - template: /eng/pipelines/libraries/helix.yml @@ -107,7 +107,7 @@ jobs: nameSuffix: AllSubsets_CoreCLR isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }} buildArgs: -s clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) - timeoutInMinutes: 480 + timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: - template: /eng/pipelines/libraries/helix.yml diff --git a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml index b7b3774f0b5..6b8698f3bdc 100644 --- a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml +++ b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-androidemulator.yml @@ -111,7 +111,7 @@ jobs: nameSuffix: AllSubsets_Mono isExtraPlatforms: ${{ parameters.isExtraPlatformsBuild }} buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) - timeoutInMinutes: 180 + timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: - template: /eng/pipelines/libraries/helix.yml diff --git a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml index 7f10d317464..82726e28094 100644 --- a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml +++ b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslike.yml @@ -42,7 +42,7 @@ jobs: buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:IsManualOrRollingBuild=true /p:EnableAggressiveTrimming=false ${{ else }}: buildArgs: -s mono+libs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true $(_runSmokeTestsOnlyArg) /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:IsManualOrRollingBuild=true /p:EnableAggressiveTrimming=true - timeoutInMinutes: 480 + timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: - template: /eng/pipelines/libraries/helix.yml @@ -81,7 +81,7 @@ jobs: testGroup: innerloop nameSuffix: AllSubsets_Mono_RuntimeTests buildArgs: -s mono+libs -c $(_BuildConfig) - timeoutInMinutes: 480 + timeoutInMinutes: 240 # extra steps, run tests extraVariablesTemplates: - template: /eng/pipelines/common/templates/runtimes/test-variables.yml @@ -152,7 +152,7 @@ jobs: jobParameters: testGroup: innerloop nameSuffix: AllSubsets_NativeAOT_RuntimeTests - timeoutInMinutes: 480 + timeoutInMinutes: 240 buildArgs: --cross -s clr.alljits+clr.tools+clr.nativeaotruntime+clr.nativeaotlibs+libs -c $(_BuildConfig) # extra steps, run tests extraVariablesTemplates: diff --git a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml index 9f483dbbe75..03cc2d926a0 100644 --- a/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml +++ b/src/runtime/eng/pipelines/extra-platforms/runtime-extra-platforms-ioslikesimulator.yml @@ -36,7 +36,7 @@ jobs: testGroup: innerloop nameSuffix: AllSubsets_Mono buildArgs: -s mono+libs+host+packs+libs.tests -c $(_BuildConfig) /p:ArchiveTests=true $(_runSmokeTestsOnlyArg) /p:RunAOTCompilation=true /p:MonoForceInterpreter=true - timeoutInMinutes: 180 + timeoutInMinutes: 240 # extra steps, run tests postBuildSteps: - template: /eng/pipelines/libraries/helix.yml @@ -119,7 +119,7 @@ jobs: jobParameters: testGroup: innerloop nameSuffix: AllSubsets_NativeAOT_RuntimeTests - timeoutInMinutes: 240 + timeoutInMinutes: 180 buildArgs: --cross -s clr.alljits+clr.tools+clr.nativeaotruntime+clr.nativeaotlibs+libs -c $(_BuildConfig) # extra steps, run tests extraVariablesTemplates: diff --git a/src/runtime/eng/pipelines/runtime.yml b/src/runtime/eng/pipelines/runtime.yml index 305bb899368..e213156d849 100644 --- a/src/runtime/eng/pipelines/runtime.yml +++ b/src/runtime/eng/pipelines/runtime.yml @@ -931,7 +931,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_Mono buildArgs: -s mono+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true /p:EnableAdditionalTimezoneChecks=true - timeoutInMinutes: 480 + timeoutInMinutes: 120 condition: >- or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -961,7 +961,8 @@ extends: buildConfig: Release runtimeFlavor: coreclr platforms: - - android_x64 + # Tracking issue: https://github.com/dotnet/dnceng/issues/5909 + # - android_x64 - android_arm64 variables: # map dependencies variables to local variables @@ -973,7 +974,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_CoreCLR buildArgs: -s clr.runtime+clr.alljits+clr.corelib+clr.nativecorelib+clr.tools+clr.packages+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:RunSmokeTestsOnly=true - timeoutInMinutes: 480 + timeoutInMinutes: 120 condition: >- or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), @@ -1017,7 +1018,7 @@ extends: testGroup: innerloop nameSuffix: AllSubsets_Mono buildArgs: -s mono+libs+libs.tests+host+packs -c $(_BuildConfig) /p:ArchiveTests=true /p:DevTeamProvisioning=- /p:RunAOTCompilation=true /p:RunSmokeTestsOnly=true /p:BuildTestsOnHelix=true /p:EnableAdditionalTimezoneChecks=true /p:UsePortableRuntimePack=false /p:EnableAggressiveTrimming=true - timeoutInMinutes: 480 + timeoutInMinutes: 120 condition: >- or( eq(stageDependencies.EvaluatePaths.evaluate_paths.outputs['SetPathVars_libraries.containsChange'], true), diff --git a/src/runtime/src/coreclr/debug/daccess/dacdbiimpl.cpp b/src/runtime/src/coreclr/debug/daccess/dacdbiimpl.cpp index 80f3ca01758..a676f7f5fed 100644 --- a/src/runtime/src/coreclr/debug/daccess/dacdbiimpl.cpp +++ b/src/runtime/src/coreclr/debug/daccess/dacdbiimpl.cpp @@ -4963,9 +4963,21 @@ void DacDbiInterfaceImpl::Hijack( // Setup context for hijack // T_CONTEXT ctx; +#if !defined(CROSS_COMPILE) && !defined(TARGET_WINDOWS) && (defined(DTCONTEXT_IS_AMD64) || defined(DTCONTEXT_IS_ARM64)) + // If the host or target is not Windows, then we can assume that the DT_CONTEXT + // is the same as the T_CONTEXT, except for the XSTATE registers. + static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT does not include the XSTATE registers"); +#else + // Since Dac + DBI are tightly coupled, context sizes should be the same. + static_assert(sizeof(DT_CONTEXT) == sizeof(T_CONTEXT), "DT_CONTEXT size must equal the T_CONTEXT size"); +#endif HRESULT hr = m_pTarget->GetThreadContext( dwThreadId, - CONTEXT_FULL, + CONTEXT_FULL | CONTEXT_FLOATING_POINT +#ifdef CONTEXT_EXTENDED_REGISTERS + | CONTEXT_EXTENDED_REGISTERS +#endif + , sizeof(DT_CONTEXT), (BYTE*) &ctx); IfFailThrow(hr); diff --git a/src/runtime/src/coreclr/debug/daccess/stdafx.h b/src/runtime/src/coreclr/debug/daccess/stdafx.h index bb7b7b2365d..bff6a4f6603 100644 --- a/src/runtime/src/coreclr/debug/daccess/stdafx.h +++ b/src/runtime/src/coreclr/debug/daccess/stdafx.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include diff --git a/src/runtime/src/coreclr/debug/di/process.cpp b/src/runtime/src/coreclr/debug/di/process.cpp index 28de989969e..132e8ab031d 100644 --- a/src/runtime/src/coreclr/debug/di/process.cpp +++ b/src/runtime/src/coreclr/debug/di/process.cpp @@ -5061,6 +5061,23 @@ void CordbProcess::RawDispatchEvent( case DB_IPCE_LOAD_MODULE: { + LOG((LF_CORDB, LL_INFO100, + "RCET::HRCE: load module (includes assembly loading) on thread %#x Asm:0x%08x AD:0x%08x \n", + dwVolatileThreadId, + VmPtrToCookie(pEvent->LoadModuleData.vmDomainAssembly), + VmPtrToCookie(pEvent->vmAppDomain))); + + _ASSERTE (pAppDomain != NULL); + + // Determine if this Assembly is cached. + CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->LoadModuleData.vmDomainAssembly); + _ASSERTE(pAssembly != NULL); // throws on error + + // If created, or have, an Assembly, notify callback. + { + PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); + hr = pCallback1->LoadAssembly(pAppDomain, pAssembly); + } _ASSERTE (pAppDomain != NULL); CordbModule * pModule = pAppDomain->LookupOrCreateModule(pEvent->LoadModuleData.vmDomainAssembly); @@ -5375,29 +5392,6 @@ void CordbProcess::RawDispatchEvent( break; - case DB_IPCE_LOAD_ASSEMBLY: - { - LOG((LF_CORDB, LL_INFO100, - "RCET::HRCE: load assembly on thread %#x Asm:0x%08x AD:0x%08x \n", - dwVolatileThreadId, - VmPtrToCookie(pEvent->AssemblyData.vmDomainAssembly), - VmPtrToCookie(pEvent->vmAppDomain))); - - _ASSERTE (pAppDomain != NULL); - - // Determine if this Assembly is cached. - CordbAssembly * pAssembly = pAppDomain->LookupOrCreateAssembly(pEvent->AssemblyData.vmDomainAssembly); - _ASSERTE(pAssembly != NULL); // throws on error - - // If created, or have, an Assembly, notify callback. - { - PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent); - hr = pCallback1->LoadAssembly(pAppDomain, pAssembly); - } - } - - break; - case DB_IPCE_UNLOAD_ASSEMBLY: { LOG((LF_CORDB, LL_INFO100, "RCET::DRCE: unload assembly on thread %#x Asm:0x%x AD:0x%x\n", @@ -13281,9 +13275,9 @@ void CordbProcess::HandleDebugEventForInteropDebugging(const DEBUG_EVENT * pEven LOG((LF_CORDB, LL_INFO100000, "W32ET::W32EL: hijack complete will restore context...\n")); DT_CONTEXT tempContext = { 0 }; #if defined(DT_CONTEXT_EXTENDED_REGISTERS) - tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS; + tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS; #else - tempContext.ContextFlags = DT_CONTEXT_FULL; + tempContext.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT; #endif HRESULT hr = pUnmanagedThread->GetThreadContext(&tempContext); _ASSERTE(SUCCEEDED(hr)); diff --git a/src/runtime/src/coreclr/debug/di/rsthread.cpp b/src/runtime/src/coreclr/debug/di/rsthread.cpp index 8b9ec41240e..07e591d15fb 100644 --- a/src/runtime/src/coreclr/debug/di/rsthread.cpp +++ b/src/runtime/src/coreclr/debug/di/rsthread.cpp @@ -3706,9 +3706,9 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync() // to avoid getting incomplete information and corrupt the thread context DT_CONTEXT context; #if defined(DT_CONTEXT_EXTENDED_REGISTERS) - context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS; + context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS; #else - context.ContextFlags = DT_CONTEXT_FULL; + context.ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT; #endif BOOL succ = DbiGetThreadContext(m_handle, &context); _ASSERTE(succ); @@ -3719,9 +3719,9 @@ HRESULT CordbUnmanagedThread::SetupFirstChanceHijackForSync() LOG((LF_CORDB, LL_ERROR, "CUT::SFCHFS: DbiGetThreadContext error=0x%x\n", error)); } #if defined(DT_CONTEXT_EXTENDED_REGISTERS) - GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_EXTENDED_REGISTERS; + GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT | DT_CONTEXT_EXTENDED_REGISTERS; #else - GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL; + GetHijackCtx()->ContextFlags = DT_CONTEXT_FULL | DT_CONTEXT_FLOATING_POINT; #endif CORDbgCopyThreadContext(GetHijackCtx(), &context); LOG((LF_CORDB, LL_INFO10000, "CUT::SFCHFS: thread=0x%x Hijacking for sync. Original context is:\n", this)); diff --git a/src/runtime/src/coreclr/debug/ee/controller.cpp b/src/runtime/src/coreclr/debug/ee/controller.cpp index a7bed1a1001..f7dfde2ae67 100644 --- a/src/runtime/src/coreclr/debug/ee/controller.cpp +++ b/src/runtime/src/coreclr/debug/ee/controller.cpp @@ -67,9 +67,79 @@ bool DebuggerControllerPatch::IsSafeForStackTrace() } +#ifndef DACCESS_COMPILE #ifndef FEATURE_EMULATE_SINGLESTEP -// returns a pointer to the shared buffer. each call will AddRef() the object -// before returning it so callers only need to Release() when they're finished with it. + +// +// We have to have a whole separate function for this because you +// can't use __try in a function that requires object unwinding... +// + +LONG FilterAccessViolation2(LPEXCEPTION_POINTERS ep, PVOID pv) +{ + LIMITED_METHOD_CONTRACT; + + return (ep->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) + ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} + +// This helper is required because the AVInRuntimeImplOkayHolder can not +// be directly placed inside the scope of a PAL_TRY +void _CopyInstructionBlockHelper(BYTE* to, const BYTE* from) +{ + AVInRuntimeImplOkayHolder AVOkay; + + // This function only copies the portion of the instruction that follows the + // breakpoint opcode, not the breakpoint itself + to += CORDbg_BREAK_INSTRUCTION_SIZE; + from += CORDbg_BREAK_INSTRUCTION_SIZE; + + // If an AV occurs because we walked off a valid page then we need + // to be certain that all bytes on the previous page were copied. + // We are certain that we copied enough bytes to contain the instruction + // because it must have fit within the valid page. + for (int i = 0; i < MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE; i++) + { + *to++ = *from++; + } + +} + +// WARNING: this function skips copying the first CORDbg_BREAK_INSTRUCTION_SIZE bytes by design +// See the comment at the callsite in DebuggerPatchSkip::DebuggerPatchSkip for more details on +// this +void DebuggerControllerPatch::CopyInstructionBlock(BYTE *to, const BYTE* from) +{ + // We wrap the memcpy in an exception handler to handle the + // extremely rare case where we're copying an instruction off the + // end of a method that is also at the end of a page, and the next + // page is unmapped. + struct Param + { + BYTE *to; + const BYTE* from; + } param; + param.to = to; + param.from = from; + PAL_TRY(Param *, pParam, ¶m) + { + _CopyInstructionBlockHelper(pParam->to, pParam->from); + } + PAL_EXCEPT_FILTER(FilterAccessViolation2) + { + // The whole point is that if we copy up the AV, then + // that's enough to execute, otherwise we would not have been + // able to execute the code anyway. So we just ignore the + // exception. + LOG((LF_CORDB, LL_INFO10000, + "DCP::CIP: AV copying instruction block ignored.\n")); + } + PAL_ENDTRY +} + + +// Creates a new shared patch bypass buffer +// AddRef() before returning it so callers need to Release() when they're finished with it. SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBuffer() { CONTRACTL @@ -79,27 +149,110 @@ SharedPatchBypassBuffer* DebuggerControllerPatch::GetOrCreateSharedPatchBypassBu } CONTRACTL_END; - if (m_pSharedPatchBypassBuffer == NULL) + if (m_pSharedPatchBypassBuffer != NULL) { - void *pSharedPatchBypassBufferRX = g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(SharedPatchBypassBuffer)); + m_pSharedPatchBypassBuffer->AddRef(); + return m_pSharedPatchBypassBuffer; + } + + // NOTE: in order to correctly single-step RIP-relative writes on multiple threads we need to set up + // a shared buffer with the instruction and a buffer for the RIP-relative value so that all threads + // are working on the same copy. as the single-steps complete the modified data in the buffer is + // copied back to the real address to ensure proper execution of the program. + + SharedPatchBypassBuffer *pSharedPatchBypassBufferRX = (SharedPatchBypassBuffer*)g_pDebugger->GetInteropSafeExecutableHeap()->Alloc(sizeof(SharedPatchBypassBuffer)); #if defined(HOST_OSX) && defined(HOST_ARM64) - ExecutableWriterHolder sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX, sizeof(SharedPatchBypassBuffer)); - void *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW(); + ExecutableWriterHolder sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX, sizeof(SharedPatchBypassBuffer)); + SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW(); #else // HOST_OSX && HOST_ARM64 - void *pSharedPatchBypassBufferRW = pSharedPatchBypassBufferRX; + SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = pSharedPatchBypassBufferRX; #endif // HOST_OSX && HOST_ARM64 - new (pSharedPatchBypassBufferRW) SharedPatchBypassBuffer(); - m_pSharedPatchBypassBuffer = (SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX; - - _ASSERTE(m_pSharedPatchBypassBuffer); - TRACE_ALLOC(m_pSharedPatchBypassBuffer); - } + new (pSharedPatchBypassBufferRW) SharedPatchBypassBuffer(); + m_pSharedPatchBypassBuffer = (SharedPatchBypassBuffer*)pSharedPatchBypassBufferRX; + _ASSERTE(m_pSharedPatchBypassBuffer); + TRACE_ALLOC(m_pSharedPatchBypassBuffer); m_pSharedPatchBypassBuffer->AddRef(); + BYTE* patchBypassRW = pSharedPatchBypassBufferRW->PatchBypass; + BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass; + + LOG((LF_CORDB, LL_INFO10000, "DCP::CSPBB: Patch skip for opcode 0x%.4x at address %p buffer allocated at 0x%.8x\n", this->opcode, this->address, m_pSharedPatchBypassBuffer)); + + // CopyInstructionBlock copies all the code bytes except the breakpoint byte(s). + _ASSERTE( this->IsBound() ); + CopyInstructionBlock(patchBypassRW, (const BYTE *)this->address); + + // Technically, we could create a patch skipper for an inactive patch, but we rely on the opcode being + // set here. + _ASSERTE( this->IsActivated() ); + CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypassRW, this->opcode); + + LOG((LF_CORDB, LL_EVERYTHING, "DCP::CSPBB: SetInstruction was called\n")); + + // + // Look at instruction to get some attributes + // + InstructionAttribute instrAttrib = { 0 }; + NativeWalker::DecodeInstructionForPatchSkip(patchBypassRX, &instrAttrib); + +#if defined(TARGET_AMD64) + // The code below handles RIP-relative addressing on AMD64. The original implementation made the assumption that + // we are only using RIP-relative addressing to access read-only data (see VSW 246145 for more information). This + // has since been expanded to handle RIP-relative writes as well. + if (instrAttrib.m_dwOffsetToDisp != 0) + { + _ASSERTE(pSharedPatchBypassBufferRW != NULL); + _ASSERTE(instrAttrib.m_cbInstr != 0); + + // + // Populate the RIP-relative buffer with the current value if needed + // + + BYTE* bufferBypassRW = pSharedPatchBypassBufferRW->BypassBuffer; + + // Overwrite the *signed* displacement. + int dwOldDisp = *(int*)(&patchBypassRX[instrAttrib.m_dwOffsetToDisp]); + int dwNewDisp = offsetof(SharedPatchBypassBuffer, BypassBuffer) - + (offsetof(SharedPatchBypassBuffer, PatchBypass) + instrAttrib.m_cbInstr); + *(int*)(&patchBypassRW[instrAttrib.m_dwOffsetToDisp]) = dwNewDisp; + + // This could be an LEA, which we'll just have to change into a MOV and copy the original address. + if (((patchBypassRX[0] == 0x4C) || (patchBypassRX[0] == 0x48)) && (patchBypassRX[1] == 0x8d)) + { + patchBypassRW[1] = 0x8b; // MOV reg, mem + _ASSERTE((int)sizeof(void*) <= SharedPatchBypassBuffer::cbBufferBypass); + *(void**)bufferBypassRW = (void*)(this->address + instrAttrib.m_cbInstr + dwOldDisp); + } + else + { + _ASSERTE(instrAttrib.m_cOperandSize <= SharedPatchBypassBuffer::cbBufferBypass); + // Copy the data into our buffer. + memcpy(bufferBypassRW, this->address + instrAttrib.m_cbInstr + dwOldDisp, instrAttrib.m_cOperandSize); + + if (instrAttrib.m_fIsWrite) + { + // save the actual destination address and size so when we TriggerSingleStep() we can update the value + pSharedPatchBypassBufferRW->RipTargetFixup = (UINT_PTR)(this->address + instrAttrib.m_cbInstr + dwOldDisp); + pSharedPatchBypassBufferRW->RipTargetFixupSize = instrAttrib.m_cOperandSize; + } + } + } + + #endif // TARGET_AMD64 + + m_pSharedPatchBypassBuffer->SetInstructionAttrib(instrAttrib); + + // Since we just created a new buffer of code, but the CPU caches code and may + // not be aware of our changes. This should force the CPU to dump any cached + // instructions it has in this region and load the new ones from memory + FlushInstructionCache(GetCurrentProcess(), patchBypassRW + CORDbg_BREAK_INSTRUCTION_SIZE, + MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE); + return m_pSharedPatchBypassBuffer; } #endif // !FEATURE_EMULATE_SINGLESTEP +#endif // !DACCESS_COMPILE // @todo - remove all this splicing trash // This Sort/Splice stuff just reorders the patches within a particular chain such @@ -4509,53 +4662,9 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread, // the single-step emulation itself. #ifndef FEATURE_EMULATE_SINGLESTEP - // NOTE: in order to correctly single-step RIP-relative writes on multiple threads we need to set up - // a shared buffer with the instruction and a buffer for the RIP-relative value so that all threads - // are working on the same copy. as the single-steps complete the modified data in the buffer is - // copied back to the real address to ensure proper execution of the program. - - // - // Create the shared instruction block. this will also create the shared RIP-relative buffer - // - + _ASSERTE(DebuggerController::HasLock()); m_pSharedPatchBypassBuffer = patch->GetOrCreateSharedPatchBypassBuffer(); -#if defined(HOST_OSX) && defined(HOST_ARM64) - ExecutableWriterHolder sharedPatchBypassBufferWriterHolder((SharedPatchBypassBuffer*)m_pSharedPatchBypassBuffer, sizeof(SharedPatchBypassBuffer)); - SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = sharedPatchBypassBufferWriterHolder.GetRW(); -#else // HOST_OSX && HOST_ARM64 - SharedPatchBypassBuffer *pSharedPatchBypassBufferRW = m_pSharedPatchBypassBuffer; -#endif // HOST_OSX && HOST_ARM64 - - BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass; - BYTE* patchBypassRW = pSharedPatchBypassBufferRW->PatchBypass; - LOG((LF_CORDB, LL_INFO10000, "DPS::DPS: Patch skip for opcode 0x%.4x at address %p buffer allocated at 0x%.8x\n", patch->opcode, patch->address, m_pSharedPatchBypassBuffer)); - - // Copy the instruction block over to the patch skip - // WARNING: there used to be an issue here because CopyInstructionBlock copied the breakpoint from the - // jitted code stream into the patch buffer. Further below CORDbgSetInstruction would correct the - // first instruction. This buffer is shared by all threads so if another thread executed the buffer - // between this thread's execution of CopyInstructionBlock and CORDbgSetInstruction the wrong - // code would be executed. The bug has been fixed by changing CopyInstructionBlock to only copy - // the code bytes after the breakpoint. - // You might be tempted to stop copying the code at all, however that wouldn't work well with rejit. - // If we skip a breakpoint that is sitting at the beginning of a method, then the profiler rejits that - // method causing a jump-stamp to be placed, then we skip the breakpoint again, we need to make sure - // the 2nd skip executes the new jump-stamp code and not the original method prologue code. Copying - // the code every time ensures that we have the most up-to-date version of the code in the buffer. - _ASSERTE( patch->IsBound() ); - CopyInstructionBlock(patchBypassRW, (const BYTE *)patch->address); - - // Technically, we could create a patch skipper for an inactive patch, but we rely on the opcode being - // set here. - _ASSERTE( patch->IsActivated() ); - CORDbgSetInstruction((CORDB_ADDRESS_TYPE *)patchBypassRW, patch->opcode); - - LOG((LF_CORDB, LL_EVERYTHING, "SetInstruction was called\n")); - // - // Look at instruction to get some attributes - // - - NativeWalker::DecodeInstructionForPatchSkip(patchBypassRX, &(m_instrAttrib)); + m_instrAttrib = m_pSharedPatchBypassBuffer->GetInstructionAttrib(); #ifdef OUT_OF_PROCESS_SETTHREADCONTEXT if (g_pDebugInterface->IsOutOfProcessSetContextEnabled() && m_instrAttrib.m_fIsCall) @@ -4564,51 +4673,6 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread, } #endif -#if defined(TARGET_AMD64) - - // The code below handles RIP-relative addressing on AMD64. The original implementation made the assumption that - // we are only using RIP-relative addressing to access read-only data (see VSW 246145 for more information). This - // has since been expanded to handle RIP-relative writes as well. - if (m_instrAttrib.m_dwOffsetToDisp != 0 && !IsInPlaceSingleStep()) - { - _ASSERTE(m_instrAttrib.m_cbInstr != 0); - - // - // Populate the RIP-relative buffer with the current value if needed - // - - BYTE* bufferBypassRW = pSharedPatchBypassBufferRW->BypassBuffer; - - // Overwrite the *signed* displacement. - int dwOldDisp = *(int*)(&patchBypassRX[m_instrAttrib.m_dwOffsetToDisp]); - int dwNewDisp = offsetof(SharedPatchBypassBuffer, BypassBuffer) - - (offsetof(SharedPatchBypassBuffer, PatchBypass) + m_instrAttrib.m_cbInstr); - *(int*)(&patchBypassRW[m_instrAttrib.m_dwOffsetToDisp]) = dwNewDisp; - - // This could be an LEA, which we'll just have to change into a MOV and copy the original address. - if (((patchBypassRX[0] == 0x4C) || (patchBypassRX[0] == 0x48)) && (patchBypassRX[1] == 0x8d)) - { - patchBypassRW[1] = 0x8b; // MOV reg, mem - _ASSERTE((int)sizeof(void*) <= SharedPatchBypassBuffer::cbBufferBypass); - *(void**)bufferBypassRW = (void*)(patch->address + m_instrAttrib.m_cbInstr + dwOldDisp); - } - else - { - _ASSERTE(m_instrAttrib.m_cOperandSize <= SharedPatchBypassBuffer::cbBufferBypass); - // Copy the data into our buffer. - memcpy(bufferBypassRW, patch->address + m_instrAttrib.m_cbInstr + dwOldDisp, m_instrAttrib.m_cOperandSize); - - if (m_instrAttrib.m_fIsWrite) - { - // save the actual destination address and size so when we TriggerSingleStep() we can update the value - pSharedPatchBypassBufferRW->RipTargetFixup = (UINT_PTR)(patch->address + m_instrAttrib.m_cbInstr + dwOldDisp); - pSharedPatchBypassBufferRW->RipTargetFixupSize = m_instrAttrib.m_cOperandSize; - } - } - } - -#endif // TARGET_AMD64 - #endif // !FEATURE_EMULATE_SINGLESTEP // Signals our thread that the debugger will be manipulating the context @@ -4672,7 +4736,9 @@ DebuggerPatchSkip::DebuggerPatchSkip(Thread *thread, #else // FEATURE_EMULATE_SINGLESTEP #ifdef TARGET_ARM64 - patchBypassRX = NativeWalker::SetupOrSimulateInstructionForPatchSkip(context, m_pSharedPatchBypassBuffer, (const BYTE *)patch->address, patch->opcode); + BYTE* patchBypassRX = NativeWalker::SetupOrSimulateInstructionForPatchSkip(context, m_pSharedPatchBypassBuffer, (const BYTE *)patch->address, patch->opcode); +#else + BYTE* patchBypassRX = m_pSharedPatchBypassBuffer->PatchBypass; #endif //TARGET_ARM64 if (!IsInPlaceSingleStep()) @@ -4742,80 +4808,6 @@ void DebuggerPatchSkip::DebuggerDetachClean() #endif // !FEATURE_EMULATE_SINGLESTEP } - -// -// We have to have a whole separate function for this because you -// can't use __try in a function that requires object unwinding... -// - -LONG FilterAccessViolation2(LPEXCEPTION_POINTERS ep, PVOID pv) -{ - LIMITED_METHOD_CONTRACT; - - return (ep->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) - ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; -} - -// This helper is required because the AVInRuntimeImplOkayHolder can not -// be directly placed inside the scope of a PAL_TRY -void _CopyInstructionBlockHelper(BYTE* to, const BYTE* from) -{ - AVInRuntimeImplOkayHolder AVOkay; - - // This function only copies the portion of the instruction that follows the - // breakpoint opcode, not the breakpoint itself - to += CORDbg_BREAK_INSTRUCTION_SIZE; - from += CORDbg_BREAK_INSTRUCTION_SIZE; - - // If an AV occurs because we walked off a valid page then we need - // to be certain that all bytes on the previous page were copied. - // We are certain that we copied enough bytes to contain the instruction - // because it must have fit within the valid page. - for (int i = 0; i < MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE; i++) - { - *to++ = *from++; - } - -} - -// WARNING: this function skips copying the first CORDbg_BREAK_INSTRUCTION_SIZE bytes by design -// See the comment at the callsite in DebuggerPatchSkip::DebuggerPatchSkip for more details on -// this -void DebuggerPatchSkip::CopyInstructionBlock(BYTE *to, const BYTE* from) -{ - // We wrap the memcpy in an exception handler to handle the - // extremely rare case where we're copying an instruction off the - // end of a method that is also at the end of a page, and the next - // page is unmapped. - struct Param - { - BYTE *to; - const BYTE* from; - } param; - param.to = to; - param.from = from; - PAL_TRY(Param *, pParam, ¶m) - { - _CopyInstructionBlockHelper(pParam->to, pParam->from); - } - PAL_EXCEPT_FILTER(FilterAccessViolation2) - { - // The whole point is that if we copy up the AV, then - // that's enough to execute, otherwise we would not have been - // able to execute the code anyway. So we just ignore the - // exception. - LOG((LF_CORDB, LL_INFO10000, - "DPS::DPS: AV copying instruction block ignored.\n")); - } - PAL_ENDTRY - - // We just created a new buffer of code, but the CPU caches code and may - // not be aware of our changes. This should force the CPU to dump any cached - // instructions it has in this region and load the new ones from memory - FlushInstructionCache(GetCurrentProcess(), to + CORDbg_BREAK_INSTRUCTION_SIZE, - MAX_INSTRUCTION_LENGTH - CORDbg_BREAK_INSTRUCTION_SIZE); -} - TP_RESULT DebuggerPatchSkip::TriggerPatch(DebuggerControllerPatch *patch, Thread *thread, TRIGGER_WHY tyWhy) diff --git a/src/runtime/src/coreclr/debug/ee/controller.h b/src/runtime/src/coreclr/debug/ee/controller.h index b02cd2802d9..32138edc36a 100644 --- a/src/runtime/src/coreclr/debug/ee/controller.h +++ b/src/runtime/src/coreclr/debug/ee/controller.h @@ -312,7 +312,11 @@ class SharedPatchBypassBuffer UINT_PTR RipTargetFixup; #endif + const InstructionAttribute& GetInstructionAttrib() { return m_instrAttrib; } + void SetInstructionAttrib(const InstructionAttribute& instrAttrib) { m_instrAttrib = instrAttrib; } + private: + InstructionAttribute m_instrAttrib; // info about the instruction being skipped over const static DWORD SentinelValue = 0xffffffff; LONG m_refCount; }; @@ -550,10 +554,13 @@ struct DebuggerControllerPatch // Is this patch at a position at which it's safe to take a stack? bool IsSafeForStackTrace(); +#ifndef DACCESS_COMPILE #ifndef FEATURE_EMULATE_SINGLESTEP // gets a pointer to the shared buffer SharedPatchBypassBuffer* GetOrCreateSharedPatchBypassBuffer(); + void CopyInstructionBlock(BYTE *to, const BYTE* from); + // entry point for general initialization when the controller is being created void Initialize() { @@ -567,6 +574,7 @@ struct DebuggerControllerPatch m_pSharedPatchBypassBuffer->Release(); } #endif // !FEATURE_EMULATE_SINGLESTEP +#endif // !DACCESS_COMPILE void LogInstance() { @@ -1515,8 +1523,6 @@ class DebuggerPatchSkip : public DebuggerController virtual DEBUGGER_CONTROLLER_TYPE GetDCType(void) { return DEBUGGER_CONTROLLER_PATCH_SKIP; } - void CopyInstructionBlock(BYTE *to, const BYTE* from); - void DecodeInstruction(CORDB_ADDRESS_TYPE *code); void DebuggerDetachClean(); diff --git a/src/runtime/src/coreclr/debug/ee/debugger.cpp b/src/runtime/src/coreclr/debug/ee/debugger.cpp index 9a935112a09..7d7c4e9b96b 100644 --- a/src/runtime/src/coreclr/debug/ee/debugger.cpp +++ b/src/runtime/src/coreclr/debug/ee/debugger.cpp @@ -9250,62 +9250,6 @@ void Debugger::SendCreateAppDomainEvent(AppDomain * pRuntimeAppDomain) } - -// -// LoadAssembly is called when a new Assembly gets loaded. -// -void Debugger::LoadAssembly(DomainAssembly * pDomainAssembly) -{ - CONTRACTL - { - MAY_DO_HELPER_THREAD_DUTY_THROWS_CONTRACT; - MAY_DO_HELPER_THREAD_DUTY_GC_TRIGGERS_CONTRACT; - } - CONTRACTL_END; - - if (CORDBUnrecoverableError(this)) - return; - - LOG((LF_CORDB, LL_INFO100, "D::LA: Load Assembly Asy:0x%p AD:0x%p which:%s\n", - pDomainAssembly, AppDomain::GetCurrentDomain(), pDomainAssembly->GetAssembly()->GetDebugName() )); - - if (!CORDebuggerAttached()) - { - return; - } - - Thread *pThread = g_pEEInterface->GetThread(); - SENDIPCEVENT_BEGIN(this, pThread) - - - if (CORDebuggerAttached()) - { - // Send a load assembly event to the Right Side. - DebuggerIPCEvent* ipce = m_pRCThread->GetIPCEventSendBuffer(); - InitIPCEvent(ipce, - DB_IPCE_LOAD_ASSEMBLY, - pThread); - - ipce->AssemblyData.vmDomainAssembly.SetRawPtr(pDomainAssembly); - - m_pRCThread->SendIPCEvent(); - } - else - { - LOG((LF_CORDB,LL_INFO1000, "D::LA: Skipping SendIPCEvent because RS detached.")); - } - - // Stop all Runtime threads - if (CORDebuggerAttached()) - { - TrapAllRuntimeThreads(); - } - - SENDIPCEVENT_END; -} - - - // // UnloadAssembly is called when a Runtime thread unloads an assembly. // diff --git a/src/runtime/src/coreclr/debug/ee/debugger.h b/src/runtime/src/coreclr/debug/ee/debugger.h index 15915b00d72..79ba57770b2 100644 --- a/src/runtime/src/coreclr/debug/ee/debugger.h +++ b/src/runtime/src/coreclr/debug/ee/debugger.h @@ -2623,9 +2623,6 @@ class Debugger : public DebugInterface void SendCreateAppDomainEvent(AppDomain * pAppDomain); - // Notify the debugger that an assembly has been loaded - void LoadAssembly(DomainAssembly * pDomainAssembly); - // Notify the debugger that an assembly has been unloaded void UnloadAssembly(DomainAssembly * pDomainAssembly); diff --git a/src/runtime/src/coreclr/debug/ee/walker.h b/src/runtime/src/coreclr/debug/ee/walker.h index 63bd4cfa2fd..4dcae6d75ed 100644 --- a/src/runtime/src/coreclr/debug/ee/walker.h +++ b/src/runtime/src/coreclr/debug/ee/walker.h @@ -62,6 +62,8 @@ struct InstructionAttribute } }; +#ifndef DACCESS_COMPILE + /* ------------------------------------------------------------------------- * * Classes * ------------------------------------------------------------------------- */ @@ -280,4 +282,6 @@ class NativeWalker : public Walker }; #endif +#endif // DACCESS_COMPILE + #endif // WALKER_H_ diff --git a/src/runtime/src/coreclr/debug/inc/dbgtargetcontext.h b/src/runtime/src/coreclr/debug/inc/dbgtargetcontext.h index ea374cf8b6d..606e4954b35 100644 --- a/src/runtime/src/coreclr/debug/inc/dbgtargetcontext.h +++ b/src/runtime/src/coreclr/debug/inc/dbgtargetcontext.h @@ -474,7 +474,7 @@ typedef DECLSPEC_ALIGN(16) struct { #if !defined(CROSS_COMPILE) && !defined(TARGET_WINDOWS) -static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT must not include the SVE registers on AMD64"); +static_assert(sizeof(DT_CONTEXT) == offsetof(T_CONTEXT, XStateFeaturesMask), "DT_CONTEXT must not include the SVE registers on ARM64"); #else static_assert(sizeof(DT_CONTEXT) == sizeof(T_CONTEXT), "DT_CONTEXT size must equal the T_CONTEXT size on ARM64"); #endif diff --git a/src/runtime/src/coreclr/inc/corinfo.h b/src/runtime/src/coreclr/inc/corinfo.h index 313d67a11ec..ff0420c7995 100644 --- a/src/runtime/src/coreclr/inc/corinfo.h +++ b/src/runtime/src/coreclr/inc/corinfo.h @@ -3139,12 +3139,6 @@ class ICorDynamicInfo : public ICorStaticInfo CORINFO_CONST_LOOKUP * pResult ) = 0; - // get the synchronization handle that is passed to monXstatic function - virtual void* getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection = NULL - ) = 0; - // get slow lazy string literal helper to use (CORINFO_HELP_STRCNS*). // Returns CORINFO_HELP_UNDEF if lazy string literal helper cannot be used. virtual CorInfoHelpFunc getLazyStringLiteralHelper( diff --git a/src/runtime/src/coreclr/inc/icorjitinfoimpl_generated.h b/src/runtime/src/coreclr/inc/icorjitinfoimpl_generated.h index ee74e9c984f..472ada1cdd6 100644 --- a/src/runtime/src/coreclr/inc/icorjitinfoimpl_generated.h +++ b/src/runtime/src/coreclr/inc/icorjitinfoimpl_generated.h @@ -550,10 +550,6 @@ void getFunctionFixedEntryPoint( bool isUnsafeFunctionPointer, CORINFO_CONST_LOOKUP* pResult) override; -void* getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection) override; - CorInfoHelpFunc getLazyStringLiteralHelper( CORINFO_MODULE_HANDLE handle) override; diff --git a/src/runtime/src/coreclr/inc/jiteeversionguid.h b/src/runtime/src/coreclr/inc/jiteeversionguid.h index 79b7eda125f..7043a7fa2f5 100644 --- a/src/runtime/src/coreclr/inc/jiteeversionguid.h +++ b/src/runtime/src/coreclr/inc/jiteeversionguid.h @@ -37,11 +37,11 @@ #include -constexpr GUID JITEEVersionIdentifier = { /* 952f0344-7651-46af-8ef3-a34539af5c4a */ - 0x952f0344, - 0x7651, - 0x46af, - {0x8e, 0xf3, 0xa3, 0x45, 0x39, 0xaf, 0x5c, 0x4a} +constexpr GUID JITEEVersionIdentifier = { /* d24a67e0-9e57-4c9e-ad31-5785df2526f2 */ + 0xd24a67e0, + 0x9e57, + 0x4c9e, + {0xad, 0x31, 0x57, 0x85, 0xdf, 0x25, 0x26, 0xf2} }; #endif // JIT_EE_VERSIONING_GUID_H diff --git a/src/runtime/src/coreclr/interpreter/compiler.cpp b/src/runtime/src/coreclr/interpreter/compiler.cpp index cb585f78268..51dce8717e4 100644 --- a/src/runtime/src/coreclr/interpreter/compiler.cpp +++ b/src/runtime/src/coreclr/interpreter/compiler.cpp @@ -2157,32 +2157,34 @@ int32_t InterpCompiler::GetMethodDataItemIndex(CORINFO_METHOD_HANDLE mHandle) return GetDataItemIndex((void*)mHandle); } -int32_t InterpCompiler::GetDataItemIndexForHelperFtn(CorInfoHelpFunc ftn) +int32_t InterpCompiler::GetDataForHelperFtn(CorInfoHelpFunc ftn) { // Interpreter-TODO: Find an existing data item index for this helper if possible and reuse it CORINFO_CONST_LOOKUP ftnLookup; m_compHnd->getHelperFtn(ftn, &ftnLookup); - void* addr = ftnLookup.addr; - if (ftnLookup.accessType == IAT_VALUE) - { - // We can't use the 1 bit to mark indirect addresses because it is used for real code on arm32 (the thumb bit) - // So instead, we mark direct addresses with a 1 and then on the other end we will clear the 1 and re-set it as needed for thumb - addr = (void*)((size_t)addr | INTERP_DIRECT_HELPER_TAG); - } - else if (ftnLookup.accessType == IAT_PPVALUE) - NO_WAY("IAT_PPVALUE helpers not implemented in interpreter"); #ifdef DEBUG - if (!PointerInNameMap(addr)) + if (!PointerInNameMap(ftnLookup.addr)) { const char* name = CorInfoHelperToName(ftn); if (name) - AddPointerToNameMap(addr, name); + AddPointerToNameMap(ftnLookup.addr, name); } #endif - assert(ftnLookup.accessType == IAT_VALUE || ftnLookup.accessType == IAT_PVALUE); - return GetDataItemIndex(addr); + static_assert(sizeof(InterpHelperData) == sizeof(int32_t), "InterpHelperData must be the same size as an int32_t"); + + InterpHelperData result; + result.accessType = ftnLookup.accessType; + int32_t dataItemIndex = GetDataItemIndex(ftnLookup.addr); + result.addressDataItemIndex = dataItemIndex; + + if (((int32_t)result.addressDataItemIndex != dataItemIndex) || ((InfoAccessType)result.accessType != ftnLookup.accessType)) + NO_WAY("Over/underflow in GetDataForHelperFtn"); + + int32_t packed; + memcpy(&packed, &result, sizeof(result)); + return packed; } static int32_t GetLdindForType(InterpType interpType) @@ -2373,49 +2375,6 @@ bool InterpCompiler::EmitNamedIntrinsicCall(NamedIntrinsic ni, CORINFO_CLASS_HAN } } -bool InterpCompiler::EmitCallIntrinsics(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO sig) -{ - const char *className = NULL; - const char *namespaceName = NULL; - const char *methodName = m_compHnd->getMethodNameFromMetadata(method, &className, &namespaceName, NULL, 0); - - if (namespaceName && !strcmp(namespaceName, "System")) - { - if (className && !strcmp(className, "Environment")) - { - if (methodName && !strcmp(methodName, "FailFast")) - { - AddIns(INTOP_FAILFAST); // to be removed, not really an intrisic - m_pStackPointer--; - return true; - } - } - else if (className && !strcmp(className, "Object")) - { - // This is needed at this moment because we don't have support for interop - // with compiled code, but it might make sense in the future for this to remain - // in order to avoid redundant interp to jit transition. - if (methodName && !strcmp(methodName, ".ctor")) - { - AddIns(INTOP_NOP); - m_pStackPointer--; - return true; - } - } - else if (className && !strcmp(className, "GC")) - { - if (methodName && !strcmp(methodName, "Collect")) - { - AddIns(INTOP_GC_COLLECT); - // Not reducing the stack pointer because we expect the version with no arguments - return true; - } - } - } - - return false; -} - void InterpCompiler::ResolveToken(uint32_t token, CorInfoTokenKind tokenKind, CORINFO_RESOLVED_TOKEN *pResolvedToken) { pResolvedToken->tokenScope = m_compScopeHnd; @@ -2520,7 +2479,7 @@ void InterpCompiler::EmitPushHelperCall_2(const CorInfoHelpFunc ftn, const CORIN if (handleData.argType == HelperArgType::GenericResolution) { AddIns(INTOP_CALL_HELPER_P_GS); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVars2(handleData.genericVar, arg2); @@ -2529,7 +2488,7 @@ void InterpCompiler::EmitPushHelperCall_2(const CorInfoHelpFunc ftn, const CORIN else { AddIns(INTOP_CALL_HELPER_P_PS); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVar(arg2); @@ -2547,7 +2506,7 @@ void InterpCompiler::EmitPushUnboxAny(const CORINFO_GENERICHANDLE_RESULT& arg1, if (handleData.argType == HelperArgType::GenericResolution) { AddIns(INTOP_UNBOX_ANY_GENERIC); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_UNBOX); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_UNBOX); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVars2(handleData.genericVar, arg2); @@ -2556,7 +2515,7 @@ void InterpCompiler::EmitPushUnboxAny(const CORINFO_GENERICHANDLE_RESULT& arg1, else { AddIns(INTOP_UNBOX_ANY); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_UNBOX); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_UNBOX); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVar(arg2); @@ -2574,7 +2533,7 @@ void InterpCompiler::EmitPushUnboxAnyNullable(const CORINFO_GENERICHANDLE_RESULT if (handleData.argType == HelperArgType::GenericResolution) { AddIns(INTOP_CALL_HELPER_V_AGS); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_UNBOX_NULLABLE); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_UNBOX_NULLABLE); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVars2(handleData.genericVar, arg2); @@ -2583,7 +2542,7 @@ void InterpCompiler::EmitPushUnboxAnyNullable(const CORINFO_GENERICHANDLE_RESULT else { AddIns(INTOP_CALL_HELPER_V_APS); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_UNBOX_NULLABLE); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_UNBOX_NULLABLE); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVar(arg2); @@ -2601,7 +2560,7 @@ void InterpCompiler::EmitPushHelperCall_Addr2(const CorInfoHelpFunc ftn, const C if (handleData.argType == HelperArgType::GenericResolution) { AddIns(INTOP_CALL_HELPER_P_GA); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVars2(handleData.genericVar, arg2); @@ -2610,7 +2569,7 @@ void InterpCompiler::EmitPushHelperCall_Addr2(const CorInfoHelpFunc ftn, const C else { AddIns(INTOP_CALL_HELPER_P_PA); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVar(arg2); @@ -2628,7 +2587,7 @@ void InterpCompiler::EmitPushHelperCall(const CorInfoHelpFunc ftn, const CORINFO if (handleData.argType == HelperArgType::GenericResolution) { AddIns(INTOP_CALL_HELPER_P_G); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVar(handleData.genericVar); @@ -2637,7 +2596,7 @@ void InterpCompiler::EmitPushHelperCall(const CorInfoHelpFunc ftn, const CORINFO else { AddIns(INTOP_CALL_HELPER_P_P); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(ftn); + m_pLastNewIns->data[0] = GetDataForHelperFtn(ftn); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetDVar(resultVar); @@ -2789,12 +2748,6 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re } } - if (EmitCallIntrinsics(callInfo.hMethod, callInfo.sig)) - { - m_ip += 5; - return; - } - if (callInfo.thisTransform != CORINFO_NO_THIS_TRANSFORM) { assert(pConstrainedToken != NULL); @@ -3027,6 +2980,10 @@ void InterpCompiler::EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool re } } m_pLastNewIns->data[0] = GetDataItemIndex(callInfo.hMethod); + + // Ensure that the dvar does not overlap with the svars; it is incorrect for it to overlap because + // the process of initializing the result may trample the args. + m_pVars[dVar].noCallArgs = true; } else if ((callInfo.classFlags & CORINFO_FLG_ARRAY) && newObj) { @@ -3326,7 +3283,7 @@ void InterpCompiler::EmitStaticFieldAddress(CORINFO_FIELD_INFO *pFieldInfo, CORI } // Call helper to obtain thread static base address AddIns(INTOP_CALL_HELPER_P_P); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(pFieldInfo->helper); + m_pLastNewIns->data[0] = GetDataForHelperFtn(pFieldInfo->helper); m_pLastNewIns->data[1] = GetDataItemIndex(helperArg); PushInterpType(InterpTypeByRef, NULL); m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); @@ -3521,7 +3478,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) if (!kind.needsRuntimeLookup) { AddIns(INTOP_CALL_HELPER_P_P); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_INITCLASS); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_INITCLASS); m_pLastNewIns->data[1] = GetDataItemIndex(m_classHnd); PushInterpType(InterpTypeI, NULL); m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); @@ -3533,7 +3490,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) { case CORINFO_LOOKUP_CLASSPARAM: AddIns(INTOP_CALL_HELPER_P_S); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_INITCLASS); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_INITCLASS); m_pLastNewIns->SetSVar(getParamArgIndex()); PushInterpType(InterpTypeI, NULL); m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); @@ -3550,7 +3507,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) m_pStackPointer--; AddIns(INTOP_CALL_HELPER_P_SP); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_INITINSTCLASS); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_INITINSTCLASS); m_pLastNewIns->data[1] = GetDataItemIndex(m_methodHnd); m_pLastNewIns->SetSVar(thisObjMethodTablePtrVar); PushInterpType(InterpTypeI, NULL); @@ -3561,7 +3518,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) case CORINFO_LOOKUP_METHODPARAM: { AddIns(INTOP_CALL_HELPER_P_PS); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(CORINFO_HELP_INITINSTCLASS); + m_pLastNewIns->data[0] = GetDataForHelperFtn(CORINFO_HELP_INITINSTCLASS); m_pLastNewIns->data[1] = GetDataItemIndex(0); m_pLastNewIns->SetSVar(getParamArgIndex()); PushInterpType(InterpTypeI, NULL); @@ -5628,7 +5585,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) AddIns(INTOP_NEWARR_GENERIC); - m_pLastNewIns->data[0] = GetDataItemIndexForHelperFtn(helpFunc); + m_pLastNewIns->data[0] = GetDataForHelperFtn(helpFunc); m_pLastNewIns->data[1] = handleData.dataItemIndex; m_pLastNewIns->SetSVars2(handleData.genericVar, newArrLenVar); @@ -5638,7 +5595,7 @@ void InterpCompiler::GenerateCode(CORINFO_METHOD_INFO* methodInfo) { AddIns(INTOP_NEWARR); m_pLastNewIns->data[0] = GetDataItemIndex(arrayClsHnd); - m_pLastNewIns->data[1] = GetDataItemIndexForHelperFtn(helpFunc); + m_pLastNewIns->data[1] = GetDataForHelperFtn(helpFunc); m_pLastNewIns->SetSVar(newArrLenVar); m_pLastNewIns->SetDVar(m_pStackPointer[-1].var); @@ -6308,21 +6265,28 @@ void InterpCompiler::PrintPointer(void* pointer) #endif } -void InterpCompiler::PrintHelperFtn(void* helperDirectOrIndirect) +void InterpCompiler::PrintHelperFtn(int32_t _data) { - void* helperAddr = helperDirectOrIndirect; - - if (((size_t)helperDirectOrIndirect) & INTERP_DIRECT_HELPER_TAG) - { - helperAddr = (void*)(((size_t)helperDirectOrIndirect) & ~INTERP_DIRECT_HELPER_TAG); - printf(" (direct)"); - } - else - { - printf(" (indirect)"); - } + InterpHelperData data; + memcpy(&data, &_data, sizeof(int32_t)); + void *helperAddr = GetDataItemAtIndex(data.addressDataItemIndex); PrintPointer(helperAddr); + + switch (data.accessType) { + case IAT_PVALUE: + printf("(indirect) "); + break; + case IAT_PPVALUE: + printf("(double-indirect) "); + break; + case IAT_VALUE: + printf("(direct) "); + break; + default: + printf("(corrupted) "); + break; + } } void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int32_t *pData, int32_t opcode) @@ -6369,7 +6333,7 @@ void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int3 } case InterpOpGenericHelperFtn: { - PrintHelperFtn((void*)GetDataItemAtIndex(pData[0])); + PrintHelperFtn(pData[0]); InterpGenericLookup *pGenericLookup = (InterpGenericLookup*)GetAddrOfDataItemAtIndex(pData[1]); PrintInterpGenericLookup(pGenericLookup); break; @@ -6413,21 +6377,23 @@ void InterpCompiler::PrintInsData(InterpInst *ins, int32_t insOffset, const int3 } case InterpOpHelperFtnNoArgs: { - PrintHelperFtn((void*)GetDataItemAtIndex(pData[0])); + PrintHelperFtn(pData[0]); break; } case InterpOpHelperFtn: { - PrintHelperFtn((void*)GetDataItemAtIndex(pData[0])); - printf(", "); - PrintPointer((void*)GetDataItemAtIndex(pData[1])); + PrintHelperFtn(pData[0]); + if (GetDataLen(opcode) > 1) { + printf(", "); + PrintPointer((void*)GetDataItemAtIndex(pData[1])); + } break; } case InterpOpPointerHelperFtn: { PrintPointer((void*)GetDataItemAtIndex(pData[0])); printf(", "); - PrintHelperFtn((void*)GetDataItemAtIndex(pData[1])); + PrintHelperFtn(pData[1]); break; } case InterpOpPointerInt: diff --git a/src/runtime/src/coreclr/interpreter/compiler.h b/src/runtime/src/coreclr/interpreter/compiler.h index 1ea75c8db43..15d0050d074 100644 --- a/src/runtime/src/coreclr/interpreter/compiler.h +++ b/src/runtime/src/coreclr/interpreter/compiler.h @@ -527,7 +527,7 @@ class InterpCompiler void* GetDataItemAtIndex(int32_t index); void* GetAddrOfDataItemAtIndex(int32_t index); int32_t GetMethodDataItemIndex(CORINFO_METHOD_HANDLE mHandle); - int32_t GetDataItemIndexForHelperFtn(CorInfoHelpFunc ftn); + int32_t GetDataForHelperFtn(CorInfoHelpFunc ftn); void GenerateCode(CORINFO_METHOD_INFO* methodInfo); InterpBasicBlock* GenerateCodeForFinallyCallIslands(InterpBasicBlock *pNewBB, InterpBasicBlock *pPrevBB); @@ -697,7 +697,6 @@ class InterpCompiler void EmitCompareOp(int32_t opBase); void EmitCall(CORINFO_RESOLVED_TOKEN* pConstrainedToken, bool readonly, bool tailcall, bool newObj, bool isCalli); bool EmitNamedIntrinsicCall(NamedIntrinsic ni, CORINFO_CLASS_HANDLE clsHnd, CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO sig); - bool EmitCallIntrinsics(CORINFO_METHOD_HANDLE method, CORINFO_SIG_INFO sig); void EmitLdind(InterpType type, CORINFO_CLASS_HANDLE clsHnd, int32_t offset); void EmitStind(InterpType type, CORINFO_CLASS_HANDLE clsHnd, int32_t offset, bool reverseSVarOrder); void EmitLdelem(int32_t opcode, InterpType type); @@ -745,7 +744,7 @@ class InterpCompiler void PrintBBCode(InterpBasicBlock *pBB); void PrintIns(InterpInst *ins); void PrintPointer(void* pointer); - void PrintHelperFtn(void* helperAddr); + void PrintHelperFtn(int32_t _data); void PrintInsData(InterpInst *ins, int32_t offset, const int32_t *pData, int32_t opcode); void PrintCompiledCode(); void PrintCompiledIns(const int32_t *ip, const int32_t *start); diff --git a/src/runtime/src/coreclr/interpreter/interpretershared.h b/src/runtime/src/coreclr/interpreter/interpretershared.h index 210bc1c1ad3..b4bb490237e 100644 --- a/src/runtime/src/coreclr/interpreter/interpretershared.h +++ b/src/runtime/src/coreclr/interpreter/interpretershared.h @@ -17,7 +17,10 @@ #define INTERP_STACK_SLOT_SIZE 8 // Alignment of each var offset on the interpreter stack #define INTERP_STACK_ALIGNMENT 16 // Alignment of interpreter stack at the start of a frame -#define INTERP_DIRECT_HELPER_TAG 1 // When a helper ftn's address is direct we tag it with this tag bit +struct InterpHelperData { + uint32_t addressDataItemIndex : 29; + uint32_t accessType : 3; +}; struct CallStubHeader; diff --git a/src/runtime/src/coreclr/interpreter/intops.def b/src/runtime/src/coreclr/interpreter/intops.def index 8de811f7b52..0e1d73769a4 100644 --- a/src/runtime/src/coreclr/interpreter/intops.def +++ b/src/runtime/src/coreclr/interpreter/intops.def @@ -400,8 +400,6 @@ OPDEF(INTOP_LEAVE_CATCH, "leavecatch", 2, 0, 0, InterpOpBranch) OPDEF(INTOP_LOAD_EXCEPTION, "load.exception", 2, 1, 0, InterpOpNoArgs) OPDEF(INTOP_THROW_PNSE, "throw.pnse", 1, 0, 0, InterpOpNoArgs) -OPDEF(INTOP_FAILFAST, "failfast", 1, 0, 0, InterpOpNoArgs) -OPDEF(INTOP_GC_COLLECT, "gc.collect", 1, 0, 0, InterpOpNoArgs) OPDEF(INTOP_LOAD_FRAMEVAR, "load.framevar", 2, 1, 0, InterpOpNoArgs) diff --git a/src/runtime/src/coreclr/jit/ICorJitInfo_names_generated.h b/src/runtime/src/coreclr/jit/ICorJitInfo_names_generated.h index e8e089f0b1d..34972535019 100644 --- a/src/runtime/src/coreclr/jit/ICorJitInfo_names_generated.h +++ b/src/runtime/src/coreclr/jit/ICorJitInfo_names_generated.h @@ -136,7 +136,6 @@ DEF_CLR_API(getAddrOfCaptureThreadGlobal) DEF_CLR_API(getHelperFtn) DEF_CLR_API(getFunctionEntryPoint) DEF_CLR_API(getFunctionFixedEntryPoint) -DEF_CLR_API(getMethodSync) DEF_CLR_API(getLazyStringLiteralHelper) DEF_CLR_API(embedModuleHandle) DEF_CLR_API(embedClassHandle) diff --git a/src/runtime/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp b/src/runtime/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp index c2a8418e302..7ee76ced3f8 100644 --- a/src/runtime/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp +++ b/src/runtime/src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp @@ -1299,16 +1299,6 @@ void WrapICorJitInfo::getFunctionFixedEntryPoint( API_LEAVE(getFunctionFixedEntryPoint); } -void* WrapICorJitInfo::getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection) -{ - API_ENTER(getMethodSync); - void* temp = wrapHnd->getMethodSync(ftn, ppIndirection); - API_LEAVE(getMethodSync); - return temp; -} - CorInfoHelpFunc WrapICorJitInfo::getLazyStringLiteralHelper( CORINFO_MODULE_HANDLE handle) { diff --git a/src/runtime/src/coreclr/jit/assertionprop.cpp b/src/runtime/src/coreclr/jit/assertionprop.cpp index 787897de5e1..ae68b1def58 100644 --- a/src/runtime/src/coreclr/jit/assertionprop.cpp +++ b/src/runtime/src/coreclr/jit/assertionprop.cpp @@ -5633,8 +5633,8 @@ bool Compiler::optCreateJumpTableImpliedAssertions(BasicBlock* switchBb) GenTree* switchTree = switchBb->lastStmt()->GetRootNode()->gtEffectiveVal(); assert(switchTree->OperIs(GT_SWITCH)); - // bbsCount is uint32_t, but it's unlikely to be more than INT32_MAX. - noway_assert(switchBb->GetSwitchTargets()->bbsCount <= INT32_MAX); + // Case count is uint32_t, but it's unlikely to be more than INT32_MAX. + noway_assert(switchBb->GetSwitchTargets()->GetCaseCount() <= INT32_MAX); ValueNum opVN = optConservativeNormalVN(switchTree->gtGetOp1()); if (opVN == ValueNumStore::NoVN) @@ -5652,9 +5652,9 @@ bool Compiler::optCreateJumpTableImpliedAssertions(BasicBlock* switchBb) int offset = 0; vnStore->PeelOffsetsI32(&opVN, &offset); - int jumpCount = static_cast(switchBb->GetSwitchTargets()->bbsCount); - FlowEdge** jumpTable = switchBb->GetSwitchTargets()->bbsDstTab; - bool hasDefault = switchBb->GetSwitchTargets()->bbsHasDefault; + int jumpCount = static_cast(switchBb->GetSwitchTargets()->GetCaseCount()); + FlowEdge** jumpTable = switchBb->GetSwitchTargets()->GetCases(); + bool hasDefault = switchBb->GetSwitchTargets()->HasDefaultCase(); for (int jmpTargetIdx = 0; jmpTargetIdx < jumpCount; jmpTargetIdx++) { @@ -5666,14 +5666,15 @@ bool Compiler::optCreateJumpTableImpliedAssertions(BasicBlock* switchBb) int value = jmpTargetIdx - offset; // We can only make "X == caseValue" assertions for blocks with a single edge from the switch. - BasicBlock* target = jumpTable[jmpTargetIdx]->getDestinationBlock(); + FlowEdge* const edge = jumpTable[jmpTargetIdx]; + BasicBlock* const target = edge->getDestinationBlock(); if (target->GetUniquePred(this) != switchBb) { // Target block is potentially reachable from multiple blocks (outside the switch). continue; } - if (fgGetPredForBlock(target, switchBb)->getDupCount() > 1) + if (edge->getDupCount() > 1) { // We have just one predecessor (BBJ_SWITCH), but there may be multiple edges (cases) per target. continue; diff --git a/src/runtime/src/coreclr/jit/async.cpp b/src/runtime/src/coreclr/jit/async.cpp index 7a26ab4b004..6dc06714054 100644 --- a/src/runtime/src/coreclr/jit/async.cpp +++ b/src/runtime/src/coreclr/jit/async.cpp @@ -290,12 +290,11 @@ BasicBlock* Compiler::InsertTryFinallyForContextRestore(BasicBlock* block, State block->SetTargetEdge(fgAddRefPred(callFinally, block)); callFinally->SetTargetEdge(fgAddRefPred(finallyRet, callFinally)); - BBehfDesc* ehfDesc = new (this, CMK_BasicBlock) BBehfDesc; - ehfDesc->bbeCount = 1; - ehfDesc->bbeSuccs = new (this, CMK_BasicBlock) FlowEdge* [1] { + FlowEdge** succs = new (this, CMK_BasicBlock) FlowEdge* [1] { fgAddRefPred(callFinallyRet, finallyRet) }; - ehfDesc->bbeSuccs[0]->setLikelihood(1.0); + succs[0]->setLikelihood(1.0); + BBJumpTable* ehfDesc = new (this, CMK_BasicBlock) BBJumpTable(succs, 1); finallyRet->SetEhfTargets(ehfDesc); callFinallyRet->SetTargetEdge(fgAddRefPred(goToTailBlock, callFinallyRet)); @@ -2288,18 +2287,26 @@ void AsyncTransformation::CreateResumptionSwitch() // Default case. TODO-CQ: Support bbsHasDefault = false before lowering. m_resumptionBBs.push_back(m_resumptionBBs[0]); - BBswtDesc* swtDesc = new (m_comp, CMK_BasicBlock) BBswtDesc; - swtDesc->bbsCount = (unsigned)m_resumptionBBs.size(); - swtDesc->bbsHasDefault = true; - swtDesc->bbsDstTab = new (m_comp, CMK_Async) FlowEdge*[m_resumptionBBs.size()]; + const size_t numCases = m_resumptionBBs.size(); + FlowEdge** const cases = new (m_comp, CMK_FlowEdge) FlowEdge*[numCases * 2]; + FlowEdge** const succs = cases + numCases; + unsigned numUniqueSuccs = 0; - weight_t stateLikelihood = 1.0 / m_resumptionBBs.size(); - for (size_t i = 0; i < m_resumptionBBs.size(); i++) + const weight_t stateLikelihood = 1.0 / m_resumptionBBs.size(); + for (size_t i = 0; i < numCases; i++) { - swtDesc->bbsDstTab[i] = m_comp->fgAddRefPred(m_resumptionBBs[i], switchBB); - swtDesc->bbsDstTab[i]->setLikelihood(stateLikelihood); + FlowEdge* const edge = m_comp->fgAddRefPred(m_resumptionBBs[i], switchBB); + edge->setLikelihood(stateLikelihood); + cases[i] = edge; + + if (edge->getDupCount() == 1) + { + succs[numUniqueSuccs++] = edge; + } } + BBswtDesc* const swtDesc = + new (m_comp, CMK_BasicBlock) BBswtDesc(cases, (unsigned)numCases, succs, numUniqueSuccs, true); switchBB->SetSwitch(swtDesc); } diff --git a/src/runtime/src/coreclr/jit/block.cpp b/src/runtime/src/coreclr/jit/block.cpp index 52f860ff736..a363e56c629 100644 --- a/src/runtime/src/coreclr/jit/block.cpp +++ b/src/runtime/src/coreclr/jit/block.cpp @@ -586,39 +586,10 @@ unsigned BasicBlock::dspPreds() const void BasicBlock::dspSuccs(Compiler* compiler) { bool first = true; - - // If this is a switch, we don't want to call `Succs(Compiler*)` because it will eventually call - // `GetSwitchDescMap()`, and that will have the side-effect of allocating the unique switch descriptor map - // and/or compute this switch block's unique succ set if it is not present. Debug output functions should - // never have an effect on codegen. We also don't want to assume the unique succ set is accurate, so we - // compute it ourselves here. - if (bbKind == BBJ_SWITCH) - { - // Create a set with all the successors. - unsigned bbNumMax = compiler->fgBBNumMax; - BitVecTraits bitVecTraits(bbNumMax + 1, compiler); - BitVec uniqueSuccBlocks(BitVecOps::MakeEmpty(&bitVecTraits)); - for (BasicBlock* const bTarget : SwitchTargets()) - { - BitVecOps::AddElemD(&bitVecTraits, uniqueSuccBlocks, bTarget->bbNum); - } - BitVecOps::Iter iter(&bitVecTraits, uniqueSuccBlocks); - unsigned bbNum = 0; - while (iter.NextElem(&bbNum)) - { - // Note that we will output switch successors in increasing numerical bbNum order, which is - // not related to their order in the bbSwtTargets->bbsDstTab table. - printf("%s" FMT_BB, first ? "" : ",", bbNum); - first = false; - } - } - else + for (const BasicBlock* const succ : Succs(compiler)) { - for (const BasicBlock* const succ : Succs(compiler)) - { - printf("%s" FMT_BB, first ? "" : ",", succ->bbNum); - first = false; - } + printf("%s" FMT_BB, first ? "" : ",", succ->bbNum); + first = false; } } @@ -672,12 +643,9 @@ void BasicBlock::dspKind() const } else { - const unsigned jumpCnt = bbEhfTargets->bbeCount; - FlowEdge** const jumpTab = bbEhfTargets->bbeSuccs; - - for (unsigned i = 0; i < jumpCnt; i++) + for (unsigned i = 0; i < bbEhfTargets->GetSuccCount(); i++) { - printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(jumpTab[i])); + printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(bbEhfTargets->GetSucc(i))); } } @@ -736,20 +704,20 @@ void BasicBlock::dspKind() const { printf(" ->"); - const unsigned jumpCnt = bbSwtTargets->bbsCount; - FlowEdge** const jumpTab = bbSwtTargets->bbsDstTab; + const unsigned jumpCnt = bbSwtTargets->GetCaseCount(); + FlowEdge** const jumpTab = bbSwtTargets->GetCases(); for (unsigned i = 0; i < jumpCnt; i++) { printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(jumpTab[i])); - const bool isDefault = bbSwtTargets->bbsHasDefault && (i == jumpCnt - 1); + const bool isDefault = bbSwtTargets->HasDefaultCase() && (i == jumpCnt - 1); if (isDefault) { printf("[def]"); } - const bool isDominant = bbSwtTargets->bbsHasDominantCase && (i == bbSwtTargets->bbsDominantCase); + const bool isDominant = bbSwtTargets->HasDominantCase() && (i == bbSwtTargets->GetDominantCase()); if (isDominant) { printf("[dom]"); @@ -1184,10 +1152,10 @@ unsigned BasicBlock::NumSucc() const return 0; } - return bbEhfTargets->bbeCount; + return bbEhfTargets->GetSuccCount(); case BBJ_SWITCH: - return bbSwtTargets->bbsCount; + return bbSwtTargets->GetCaseCount(); default: unreached(); @@ -1229,10 +1197,10 @@ FlowEdge* BasicBlock::GetSuccEdge(unsigned i) const } case BBJ_EHFINALLYRET: - return bbEhfTargets->bbeSuccs[i]; + return bbEhfTargets->GetSucc(i); case BBJ_SWITCH: - return bbSwtTargets->bbsDstTab[i]; + return bbSwtTargets->GetCase(i); default: unreached(); @@ -1288,7 +1256,7 @@ unsigned BasicBlock::NumSucc(Compiler* comp) return 0; } - return bbEhfTargets->bbeCount; + return bbEhfTargets->GetSuccCount(); case BBJ_CALLFINALLY: case BBJ_CALLFINALLYRET: @@ -1309,10 +1277,7 @@ unsigned BasicBlock::NumSucc(Compiler* comp) } case BBJ_SWITCH: - { - Compiler::SwitchUniqueSuccSet sd = comp->GetDescriptorForSwitch(this); - return sd.numDistinctSuccs; - } + return bbSwtTargets->GetSuccCount(); default: unreached(); @@ -1343,8 +1308,7 @@ FlowEdge* BasicBlock::GetSuccEdge(unsigned i, Compiler* comp) case BBJ_EHFINALLYRET: assert(bbEhfTargets != nullptr); - assert(i < bbEhfTargets->bbeCount); - return bbEhfTargets->bbeSuccs[i]; + return bbEhfTargets->GetSucc(i); case BBJ_CALLFINALLY: case BBJ_CALLFINALLYRET: @@ -1366,11 +1330,7 @@ FlowEdge* BasicBlock::GetSuccEdge(unsigned i, Compiler* comp) } case BBJ_SWITCH: - { - Compiler::SwitchUniqueSuccSet sd = comp->GetDescriptorForSwitch(this); - assert(i < sd.numDistinctSuccs); // Range check. - return sd.nonDuplicates[i]; - } + return bbSwtTargets->GetSucc(i); default: unreached(); @@ -1636,7 +1596,7 @@ BasicBlock* BasicBlock::New(Compiler* compiler, BBKinds kind) return block; } -BasicBlock* BasicBlock::New(Compiler* compiler, BBehfDesc* ehfTargets) +BasicBlock* BasicBlock::New(Compiler* compiler, BBJumpTable* ehfTargets) { BasicBlock* block = BasicBlock::New(compiler); block->SetEhf(ehfTargets); @@ -1758,21 +1718,6 @@ bool BasicBlock::hasEHBoundaryOut() const return KindIs(BBJ_EHFILTERRET, BBJ_EHFINALLYRET, BBJ_EHFAULTRET, BBJ_EHCATCHRET); } -//------------------------------------------------------------------------ -// BBswtDesc copy ctor: copy a switch descriptor, but don't set up the jump table -// -// Arguments: -// other - existing switch descriptor to copy (except for its jump table) -// -BBswtDesc::BBswtDesc(const BBswtDesc* other) - : bbsDstTab(nullptr) - , bbsCount(other->bbsCount) - , bbsDominantCase(other->bbsDominantCase) - , bbsHasDefault(other->bbsHasDefault) - , bbsHasDominantCase(other->bbsHasDominantCase) -{ -} - //------------------------------------------------------------------------ // BBswtDesc copy ctor: copy a switch descriptor // @@ -1781,38 +1726,33 @@ BBswtDesc::BBswtDesc(const BBswtDesc* other) // other - existing switch descriptor to copy // BBswtDesc::BBswtDesc(Compiler* comp, const BBswtDesc* other) - : bbsDstTab(nullptr) - , bbsCount(other->bbsCount) + : BBJumpTable(new(comp, CMK_FlowEdge) FlowEdge*[other->succCount + other->caseCount], other -> succCount) + , caseCount(other->caseCount) + , cases(succs + succCount) , bbsDominantCase(other->bbsDominantCase) , bbsHasDefault(other->bbsHasDefault) , bbsHasDominantCase(other->bbsHasDominantCase) { - // Allocate and fill in a new dst tab + // Fill in the new tables // - bbsDstTab = new (comp, CMK_FlowEdge) FlowEdge*[bbsCount]; - for (unsigned i = 0; i < bbsCount; i++) - { - bbsDstTab[i] = other->bbsDstTab[i]; - } + memcpy(succs, other->succs, sizeof(FlowEdge*) * succCount); + memcpy(cases, other->cases, sizeof(FlowEdge*) * caseCount); } //------------------------------------------------------------------------ -// BBehfDesc copy ctor: copy a EHFINALLYRET descriptor +// BBJumpTable copy ctor: copy a N-successor block descriptor // // Arguments: // comp - compiler instance // other - existing descriptor to copy // -BBehfDesc::BBehfDesc(Compiler* comp, const BBehfDesc* other) - : bbeCount(other->bbeCount) +BBJumpTable::BBJumpTable(Compiler* comp, const BBJumpTable* other) + : succs(new(comp, CMK_FlowEdge) FlowEdge*[other->succCount]) + , succCount(other->succCount) { - // Allocate and fill in a new dst tab + // Fill in the new jump table // - bbeSuccs = new (comp, CMK_FlowEdge) FlowEdge*[bbeCount]; - for (unsigned i = 0; i < bbeCount; i++) - { - bbeSuccs[i] = other->bbeSuccs[i]; - } + memcpy(succs, other->succs, sizeof(FlowEdge*) * succCount); } //------------------------------------------------------------------------ diff --git a/src/runtime/src/coreclr/jit/block.h b/src/runtime/src/coreclr/jit/block.h index c541fa5309c..e1ffa46cff0 100644 --- a/src/runtime/src/coreclr/jit/block.h +++ b/src/runtime/src/coreclr/jit/block.h @@ -107,7 +107,7 @@ struct BasicBlockList; struct FlowEdge; struct EHblkDsc; struct BBswtDesc; -struct BBehfDesc; +struct BBJumpTable; struct StackEntry { @@ -346,7 +346,7 @@ class BBArrayIterator } }; -// FlowEdgeArrayIterator: forward iterator for an array of FlowEdge*, such as the BBswtDesc->bbsDstTab. +// FlowEdgeArrayIterator: forward iterator for an array of FlowEdge*, such as BBJumpTable::succs. // It is an error (with assert) to yield a nullptr FlowEdge* in this array. // `m_edgeEntry` can be nullptr, but it only makes sense if both the begin and end of an iteration range are nullptr // (meaning, no actual iteration will happen). @@ -382,30 +382,16 @@ class FlowEdgeArrayIterator } }; -// BBSwitchTargetList: adapter class for forward iteration of switch targets, using range-based `for`, -// normally used via BasicBlock::SwitchTargets(), e.g.: -// for (BasicBlock* const target : block->SwitchTargets()) ... -// -class BBSwitchTargetList -{ - BBswtDesc* m_bbsDesc; - -public: - BBSwitchTargetList(BBswtDesc* bbsDesc); - BBArrayIterator begin() const; - BBArrayIterator end() const; -}; - -// BBEhfSuccList: adapter class for forward iteration of BBJ_EHFINALLYRET blocks, using range-based `for`, -// normally used via BasicBlock::EHFinallyRetSuccs(), e.g.: +// BBJumpTableList: adapter class for forward iteration of blocks with N successors, using range-based `for`, +// normally used via BasicBlock::EHFinallyRetSuccs() or BasicBlock::SwitchSuccs(), e.g.: // for (BasicBlock* const succ : block->EHFinallyRetSuccs()) ... // -class BBEhfSuccList +class BBJumpTableList { - BBehfDesc* m_bbeDesc; + BBJumpTable* m_bbJumpTable; public: - BBEhfSuccList(BBehfDesc* bbeDesc); + BBJumpTableList(BBJumpTable* bbJumpTable); BBArrayIterator begin() const; BBArrayIterator end() const; }; @@ -740,11 +726,11 @@ struct BasicBlock : private LIR::Range /* The following union describes the jump target(s) of this block */ union { - unsigned bbTargetOffs; // PC offset (temporary only) - FlowEdge* bbTargetEdge; // successor edge for block kinds with only one successor (BBJ_ALWAYS, etc) - FlowEdge* bbTrueEdge; // BBJ_COND successor edge when its condition is true (alias for bbTargetEdge) - BBswtDesc* bbSwtTargets; // switch descriptor - BBehfDesc* bbEhfTargets; // BBJ_EHFINALLYRET descriptor + unsigned bbTargetOffs; // PC offset (temporary only) + FlowEdge* bbTargetEdge; // successor edge for block kinds with only one successor (BBJ_ALWAYS, etc) + FlowEdge* bbTrueEdge; // BBJ_COND successor edge when its condition is true (alias for bbTargetEdge) + BBswtDesc* bbSwtTargets; // switch descriptor + BBJumpTable* bbEhfTargets; // BBJ_EHFINALLYRET descriptor }; // Successor edge of a BBJ_COND block if bbTrueEdge is not taken @@ -753,7 +739,7 @@ struct BasicBlock : private LIR::Range public: static BasicBlock* New(Compiler* compiler); static BasicBlock* New(Compiler* compiler, BBKinds kind); - static BasicBlock* New(Compiler* compiler, BBehfDesc* ehfTargets); + static BasicBlock* New(Compiler* compiler, BBJumpTable* ehfTargets); static BasicBlock* New(Compiler* compiler, BBswtDesc* swtTargets); static BasicBlock* New(Compiler* compiler, BBKinds kind, unsigned targetOffs); @@ -1029,19 +1015,19 @@ struct BasicBlock : private LIR::Range bbSwtTargets = swtTarget; } - BBehfDesc* GetEhfTargets() const + BBJumpTable* GetEhfTargets() const { assert(KindIs(BBJ_EHFINALLYRET)); return bbEhfTargets; } - void SetEhfTargets(BBehfDesc* ehfTarget) + void SetEhfTargets(BBJumpTable* ehfTarget) { assert(KindIs(BBJ_EHFINALLYRET)); bbEhfTargets = ehfTarget; } - void SetEhf(BBehfDesc* ehfTarget) + void SetEhf(BBJumpTable* ehfTarget) { assert(ehfTarget != nullptr); bbKind = BBJ_EHFINALLYRET; @@ -1405,23 +1391,24 @@ struct BasicBlock : private LIR::Range BasicBlock* GetSucc(unsigned i) const; BasicBlock* GetSucc(unsigned i, Compiler* comp); - // SwitchTargets: convenience method for enabling range-based `for` iteration over a switch block's targets, e.g.: - // for (BasicBlock* const bTarget : block->SwitchTargets()) ... + // SwitchSuccs: convenience method for enabling range-based `for` iteration over a switch block's unique successors, + // e.g.: + // for (BasicBlock* const bTarget : block->SwitchSuccs()) ... // - BBSwitchTargetList SwitchTargets() const + BBJumpTableList SwitchSuccs() const { assert(bbKind == BBJ_SWITCH); - return BBSwitchTargetList(bbSwtTargets); + return BBJumpTableList((BBJumpTable*)bbSwtTargets); } // EHFinallyRetSuccs: convenience method for enabling range-based `for` iteration over BBJ_EHFINALLYRET block // successors, e.g.: // for (BasicBlock* const succ : block->EHFinallyRetSuccs()) ... // - BBEhfSuccList EHFinallyRetSuccs() const + BBJumpTableList EHFinallyRetSuccs() const { assert(bbKind == BBJ_EHFINALLYRET); - return BBEhfSuccList(bbEhfTargets); + return BBJumpTableList(bbEhfTargets); } BasicBlock* GetUniquePred(Compiler* comp) const; @@ -2280,6 +2267,70 @@ class BasicBlockRangeList bool ComplexityExceeds(Compiler* comp, unsigned limit, unsigned* count = nullptr); }; +// BBJumpTable -- descriptor blocks with N successors +// +struct BBJumpTable +{ +protected: + FlowEdge** succs; // array of unique `FlowEdge*` pointing to the block's successors + unsigned succCount; // Number of unique successors + +public: + BBJumpTable() + : succs(nullptr) + , succCount(0) + { + } + + BBJumpTable(FlowEdge** succs, unsigned succCount) + : succs(succs) + , succCount(succCount) + { + } + + BBJumpTable(Compiler* comp, const BBJumpTable* other); + + FlowEdge** GetSuccs() const + { + return succs; + } + + FlowEdge* GetSucc(unsigned index) const + { + assert(index < succCount); + assert(succs != nullptr); + return succs[index]; + } + + unsigned GetSuccCount() const + { + return succCount; + } + + void SetSuccs(FlowEdge** newSuccs, unsigned newSuccCount) + { + assert((newSuccs != nullptr) || (newSuccCount == 0)); + + succs = newSuccs; + succCount = newSuccCount; + } + + void RemoveSucc(unsigned index) + { + assert(index < succCount); + assert(succs != nullptr); + + // If succEdge is not the last entry, move everything after in the table down one slot. + if ((index + 1) < succCount) + { + memmove_s(succs + index, (succCount - index) * sizeof(FlowEdge*), succs + index + 1, + (succCount - index - 1) * sizeof(FlowEdge*)); + } + + succCount--; + } +}; + // BBswtDesc -- descriptor for a switch block // // Things to know: @@ -2289,11 +2340,20 @@ class BasicBlockRangeList // allows for a degenerate switch with zero cases. Normally, the optimizer will optimize degenerate // switches with just a default case to a BBJ_ALWAYS branch, and a switch with just two cases to a BBJ_COND. // However, in debuggable code, we might not do that, so bbsCount might be 1. +// 3. BBswtDesc makes no promises about the relative positions of the 'succs' and 'cases' arrays. +// Callers are responsible for allocating these arrays during BBswtDesc creation. +// A potential optimization is to allocate one array large enough for the two; +// this is safe, because BBswtDesc does not support adding new cases/successors. // -struct BBswtDesc +struct BBswtDesc : public BBJumpTable { - FlowEdge** bbsDstTab; // case label table address - unsigned bbsCount; // count of cases (includes 'default' if bbsHasDefault) +private: + // Inherited from BBJumpTable: + // FlowEdge** succs; // array of unique `FlowEdge*` pointing to the block's successors + // unsigned succCount; // Number of unique successors + + unsigned caseCount; // count of cases (includes 'default' if bbsHasDefault) + FlowEdge** cases; // array of non-unique FlowEdge* pointing to the switch cases // Case number of most likely case // (only known with PGO, only valid if bbsHasDominantCase is true) @@ -2302,86 +2362,114 @@ struct BBswtDesc bool bbsHasDefault; // true if last switch case is a default case bool bbsHasDominantCase; // true if switch has a dominant case - BBswtDesc() - : bbsHasDefault(true) +public: + BBswtDesc(FlowEdge** succs, unsigned succCount, FlowEdge** cases, unsigned caseCount, bool hasDefault) + : BBJumpTable(succs, succCount) + , caseCount(caseCount) + , cases(cases) + , bbsDominantCase(0) + , bbsHasDefault(hasDefault) , bbsHasDominantCase(false) { } - BBswtDesc(const BBswtDesc* other); + BBswtDesc(FlowEdge** succs, + unsigned succCount, + FlowEdge** cases, + unsigned caseCount, + bool hasDefault, + unsigned dominantCase) + : BBJumpTable(succs, succCount) + , caseCount(caseCount) + , cases(cases) + , bbsDominantCase(dominantCase) + , bbsHasDefault(hasDefault) + , bbsHasDominantCase(true) + { + } BBswtDesc(Compiler* comp, const BBswtDesc* other); - void removeDefault() + FlowEdge** GetCases() const { - assert(bbsHasDefault); - assert(bbsCount > 0); - bbsHasDefault = false; - bbsCount--; + assert((cases != nullptr) || (caseCount == 0)); + return cases; } - FlowEdge* getDefault() + FlowEdge* GetCase(unsigned index) const { - assert(bbsHasDefault); - assert(bbsCount > 0); - return bbsDstTab[bbsCount - 1]; + assert(index < caseCount); + return cases[index]; } -}; -// BBSwitchTargetList out-of-class-declaration implementations (here due to C++ ordering requirements). -// + unsigned GetCaseCount() const + { + return caseCount; + } -inline BBSwitchTargetList::BBSwitchTargetList(BBswtDesc* bbsDesc) - : m_bbsDesc(bbsDesc) -{ - assert(m_bbsDesc != nullptr); - assert(m_bbsDesc->bbsDstTab != nullptr); -} + void RemoveDefaultCase() + { + assert(bbsHasDefault); + assert(caseCount > 0); + bbsHasDefault = false; + caseCount--; + } -inline BBArrayIterator BBSwitchTargetList::begin() const -{ - return BBArrayIterator(m_bbsDesc->bbsDstTab); -} + bool HasDefaultCase() const + { + return bbsHasDefault; + } -inline BBArrayIterator BBSwitchTargetList::end() const -{ - return BBArrayIterator(m_bbsDesc->bbsDstTab + m_bbsDesc->bbsCount); -} + FlowEdge* GetDefaultCase() const + { + assert(bbsHasDefault); + assert(caseCount > 0); + return cases[caseCount - 1]; + } -// BBehfDesc -- descriptor for a BBJ_EHFINALLYRET block -// -struct BBehfDesc -{ - FlowEdge** bbeSuccs; // array of `FlowEdge*` pointing to BBJ_EHFINALLYRET block successors - unsigned bbeCount; // size of `bbeSuccs` array + void SetDominantCase(unsigned dominantCase) + { + assert(!bbsHasDominantCase); + bbsDominantCase = dominantCase; + bbsHasDominantCase = true; + } - BBehfDesc() - : bbeSuccs(nullptr) - , bbeCount(0) + void RemoveDominantCase() { + assert(bbsHasDominantCase); + bbsHasDominantCase = false; } - BBehfDesc(Compiler* comp, const BBehfDesc* other); + bool HasDominantCase() const + { + return bbsHasDominantCase; + } + + unsigned GetDominantCase() const + { + assert(bbsHasDominantCase); + return bbsDominantCase; + } }; -// BBEhfSuccList out-of-class-declaration implementations (here due to C++ ordering requirements). +// BBJumpTableList out-of-class-declaration implementations (here due to C++ ordering requirements). // -inline BBEhfSuccList::BBEhfSuccList(BBehfDesc* bbeDesc) - : m_bbeDesc(bbeDesc) +inline BBJumpTableList::BBJumpTableList(BBJumpTable* bbJumpTable) + : m_bbJumpTable(bbJumpTable) { - assert(m_bbeDesc != nullptr); - assert((m_bbeDesc->bbeSuccs != nullptr) || (m_bbeDesc->bbeCount == 0)); + assert(m_bbJumpTable != nullptr); + assert((m_bbJumpTable->GetSuccs() != nullptr) || (m_bbJumpTable->GetSuccCount() == 0)); } -inline BBArrayIterator BBEhfSuccList::begin() const +inline BBArrayIterator BBJumpTableList::begin() const { - return BBArrayIterator(m_bbeDesc->bbeSuccs); + return BBArrayIterator(m_bbJumpTable->GetSuccs()); } -inline BBArrayIterator BBEhfSuccList::end() const +inline BBArrayIterator BBJumpTableList::end() const { - return BBArrayIterator(m_bbeDesc->bbeSuccs + m_bbeDesc->bbeCount); + return BBArrayIterator(m_bbJumpTable->GetSuccs() + m_bbJumpTable->GetSuccCount()); } // SuccList out-of-class-declaration implementations @@ -2439,17 +2527,17 @@ inline BasicBlock::SuccList::SuccList(const BasicBlock* block) } else { - m_begin = block->GetEhfTargets()->bbeSuccs; - m_end = block->GetEhfTargets()->bbeSuccs + block->GetEhfTargets()->bbeCount; + m_begin = block->GetEhfTargets()->GetSuccs(); + m_end = block->GetEhfTargets()->GetSuccs() + block->GetEhfTargets()->GetSuccCount(); } break; case BBJ_SWITCH: // We don't use the m_succs in-line data for switches; use the existing jump table in the block. assert(block->bbSwtTargets != nullptr); - assert(block->bbSwtTargets->bbsDstTab != nullptr); - m_begin = block->bbSwtTargets->bbsDstTab; - m_end = block->bbSwtTargets->bbsDstTab + block->bbSwtTargets->bbsCount; + assert(block->bbSwtTargets->GetCases() != nullptr); + m_begin = block->bbSwtTargets->GetCases(); + m_end = block->bbSwtTargets->GetCases() + block->bbSwtTargets->GetCaseCount(); break; default: diff --git a/src/runtime/src/coreclr/jit/clrjit.natvis b/src/runtime/src/coreclr/jit/clrjit.natvis index 424bd4e3f2d..b38738ea9ed 100644 --- a/src/runtime/src/coreclr/jit/clrjit.natvis +++ b/src/runtime/src/coreclr/jit/clrjit.natvis @@ -22,8 +22,8 @@ Documentation for VS debugger format specifiers: https://learn.microsoft.com/vis BB{bbNum,d}->BB{bbTargetEdge->m_destBlock->bbNum,d}; {bbKind,en} BB{bbNum,d}-> (BB{bbTrueEdge->m_destBlock->bbNum,d}(T),BB{bbFalseEdge->m_destBlock->bbNum,d}(F)) ; {bbKind,en} - BB{bbNum,d}; {bbKind,en}; {bbSwtTargets->bbsCount} cases - BB{bbNum,d}; {bbKind,en}; {bbEhfTargets->bbeCount} succs + BB{bbNum,d}; {bbKind,en}; {bbSwtTargets->caseCount} cases + BB{bbNum,d}; {bbKind,en}; {bbEhfTargets->succCount} succs BB{bbNum,d}; {bbKind,en} diff --git a/src/runtime/src/coreclr/jit/codegenarm64test.cpp b/src/runtime/src/coreclr/jit/codegenarm64test.cpp index a66e626a6e2..aefe56ea0f0 100644 --- a/src/runtime/src/coreclr/jit/codegenarm64test.cpp +++ b/src/runtime/src/coreclr/jit/codegenarm64test.cpp @@ -7036,95 +7036,95 @@ void CodeGen::genArm64EmitterUnitTestsSve() // IF_SVE_FE_3A theEmitter->emitIns_R_R_R_I(INS_sve_smullb, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, - INS_OPTS_SCALABLE_H); // SMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smullb, EA_SCALABLE, REG_V2, REG_V3, REG_V1, 1, - INS_OPTS_SCALABLE_H); // SMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smullt, EA_SCALABLE, REG_V4, REG_V5, REG_V2, 2, - INS_OPTS_SCALABLE_H); // SMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMULLT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smullt, EA_SCALABLE, REG_V6, REG_V7, REG_V3, 3, - INS_OPTS_SCALABLE_H); // SMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMULLT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umullb, EA_SCALABLE, REG_V8, REG_V9, REG_V4, 4, - INS_OPTS_SCALABLE_H); // UMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umullb, EA_SCALABLE, REG_V10, REG_V11, REG_V5, 5, - INS_OPTS_SCALABLE_H); // UMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umullt, EA_SCALABLE, REG_V12, REG_V13, REG_V6, 6, - INS_OPTS_SCALABLE_H); // UMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMULLT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umullt, EA_SCALABLE, REG_V14, REG_V15, REG_V7, 7, - INS_OPTS_SCALABLE_H); // UMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMULLT .S, .H, .H[] // IF_SVE_FE_3B theEmitter->emitIns_R_R_R_I(INS_sve_smullb, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, - INS_OPTS_SCALABLE_S); // SMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smullb, EA_SCALABLE, REG_V2, REG_V3, REG_V2, 1, - INS_OPTS_SCALABLE_S); // SMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smullt, EA_SCALABLE, REG_V4, REG_V5, REG_V4, 2, - INS_OPTS_SCALABLE_S); // SMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMULLT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smullt, EA_SCALABLE, REG_V6, REG_V7, REG_V6, 3, - INS_OPTS_SCALABLE_S); // SMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMULLT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umullb, EA_SCALABLE, REG_V8, REG_V9, REG_V8, 0, - INS_OPTS_SCALABLE_S); // UMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umullb, EA_SCALABLE, REG_V10, REG_V11, REG_V10, 1, - INS_OPTS_SCALABLE_S); // UMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umullt, EA_SCALABLE, REG_V12, REG_V13, REG_V12, 2, - INS_OPTS_SCALABLE_S); // UMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMULLT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umullt, EA_SCALABLE, REG_V14, REG_V15, REG_V14, 3, - INS_OPTS_SCALABLE_S); // UMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMULLT .D, .S, .S[] // IF_SVE_FG_3A theEmitter->emitIns_R_R_R_I(INS_sve_smlalb, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, - INS_OPTS_SCALABLE_H); // SMLALB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMLALB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smlalt, EA_SCALABLE, REG_V2, REG_V3, REG_V1, 1, - INS_OPTS_SCALABLE_H); // SMLALT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMLALT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smlslb, EA_SCALABLE, REG_V4, REG_V5, REG_V2, 2, - INS_OPTS_SCALABLE_H); // SMLSLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMLSLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_smlslt, EA_SCALABLE, REG_V6, REG_V7, REG_V3, 3, - INS_OPTS_SCALABLE_H); // SMLSLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SMLSLT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umlalb, EA_SCALABLE, REG_V8, REG_V9, REG_V4, 4, - INS_OPTS_SCALABLE_H); // UMLALB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMLALB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umlalt, EA_SCALABLE, REG_V10, REG_V11, REG_V5, 5, - INS_OPTS_SCALABLE_H); // UMLALT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMLALT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umlslb, EA_SCALABLE, REG_V12, REG_V13, REG_V6, 6, - INS_OPTS_SCALABLE_H); // UMLSLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMLSLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_umlslt, EA_SCALABLE, REG_V14, REG_V15, REG_V7, 7, - INS_OPTS_SCALABLE_H); // UMLSLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // UMLSLT .S, .H, .H[] // IF_SVE_FG_3B theEmitter->emitIns_R_R_R_I(INS_sve_smlalb, EA_SCALABLE, REG_V0, REG_V1, REG_V0, 0, - INS_OPTS_SCALABLE_S); // SMLALB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMLALB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smlalt, EA_SCALABLE, REG_V2, REG_V3, REG_V2, 1, - INS_OPTS_SCALABLE_S); // SMLALT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMLALT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smlslb, EA_SCALABLE, REG_V4, REG_V5, REG_V4, 2, - INS_OPTS_SCALABLE_S); // SMLSLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMLSLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_smlslt, EA_SCALABLE, REG_V6, REG_V7, REG_V6, 3, - INS_OPTS_SCALABLE_S); // SMLSLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SMLSLT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umlalb, EA_SCALABLE, REG_V8, REG_V9, REG_V8, 0, - INS_OPTS_SCALABLE_S); // UMLALB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMLALB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umlalt, EA_SCALABLE, REG_V10, REG_V11, REG_V10, 1, - INS_OPTS_SCALABLE_S); // UMLALT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMLALT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umlslb, EA_SCALABLE, REG_V12, REG_V13, REG_V12, 2, - INS_OPTS_SCALABLE_S); // UMLSLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMLSLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_umlslt, EA_SCALABLE, REG_V14, REG_V15, REG_V14, 3, - INS_OPTS_SCALABLE_S); // UMLSLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // UMLSLT .D, .S, .S[] // IF_SVE_FH_3A theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullb, EA_SCALABLE, REG_V0, REG_V2, REG_V1, 1, - INS_OPTS_SCALABLE_H); // SQDMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullb, EA_SCALABLE, REG_V4, REG_V6, REG_V3, 3, - INS_OPTS_SCALABLE_H); // SQDMULLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMULLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullt, EA_SCALABLE, REG_V8, REG_V10, REG_V5, 5, - INS_OPTS_SCALABLE_H); // SQDMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMULLT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullt, EA_SCALABLE, REG_V12, REG_V14, REG_V7, 7, - INS_OPTS_SCALABLE_H); // SQDMULLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMULLT .S, .H, .H[] // IF_SVE_FH_3B theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullb, EA_SCALABLE, REG_V0, REG_V2, REG_V0, 0, - INS_OPTS_SCALABLE_S); // SQDMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullb, EA_SCALABLE, REG_V4, REG_V6, REG_V5, 1, - INS_OPTS_SCALABLE_S); // SQDMULLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMULLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullt, EA_SCALABLE, REG_V8, REG_V10, REG_V10, 2, - INS_OPTS_SCALABLE_S); // SQDMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMULLT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmullt, EA_SCALABLE, REG_V12, REG_V14, REG_V15, 3, - INS_OPTS_SCALABLE_S); // SQDMULLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMULLT .D, .S, .S[] // IF_SVE_FI_3A theEmitter->emitIns_R_R_R_I(INS_sve_sqdmulh, EA_SCALABLE, REG_V0, REG_V1, REG_V1, 1, @@ -7158,23 +7158,23 @@ void CodeGen::genArm64EmitterUnitTestsSve() // IF_SVE_FJ_3A theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlalb, EA_SCALABLE, REG_V0, REG_V1, REG_V1, 1, - INS_OPTS_SCALABLE_H); // SQDMLALB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMLALB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlalt, EA_SCALABLE, REG_V2, REG_V3, REG_V3, 3, - INS_OPTS_SCALABLE_H); // SQDMLALT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMLALT .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlslb, EA_SCALABLE, REG_V4, REG_V5, REG_V5, 5, - INS_OPTS_SCALABLE_H); // SQDMLSLB .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMLSLB .S, .H, .H[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlslt, EA_SCALABLE, REG_V6, REG_V0, REG_V7, 7, - INS_OPTS_SCALABLE_H); // SQDMLSLT .S, .H, .H[] + INS_OPTS_SCALABLE_S); // SQDMLSLT .S, .H, .H[] // IF_SVE_FJ_3B theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlalb, EA_SCALABLE, REG_V8, REG_V9, REG_V0, 0, - INS_OPTS_SCALABLE_S); // SQDMLALB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMLALB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlalt, EA_SCALABLE, REG_V10, REG_V11, REG_V5, 1, - INS_OPTS_SCALABLE_S); // SQDMLALT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMLALT .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlslb, EA_SCALABLE, REG_V12, REG_V13, REG_V10, 2, - INS_OPTS_SCALABLE_S); // SQDMLSLB .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMLSLB .D, .S, .S[] theEmitter->emitIns_R_R_R_I(INS_sve_sqdmlslt, EA_SCALABLE, REG_V14, REG_V15, REG_V15, 3, - INS_OPTS_SCALABLE_S); // SQDMLSLT .D, .S, .S[] + INS_OPTS_SCALABLE_D); // SQDMLSLT .D, .S, .S[] // IF_SVE_FF_3A theEmitter->emitIns_R_R_R_I(INS_sve_mla, EA_SCALABLE, REG_V0, REG_V1, REG_V1, 1, diff --git a/src/runtime/src/coreclr/jit/codegencommon.cpp b/src/runtime/src/coreclr/jit/codegencommon.cpp index 22ec0490991..3e2ba356790 100644 --- a/src/runtime/src/coreclr/jit/codegencommon.cpp +++ b/src/runtime/src/coreclr/jit/codegencommon.cpp @@ -485,7 +485,7 @@ void CodeGen::genMarkLabelsForCodegen() break; case BBJ_SWITCH: - for (BasicBlock* const bTarget : block->SwitchTargets()) + for (BasicBlock* const bTarget : block->SwitchSuccs()) { JITDUMP(" " FMT_BB " : switch target\n", bTarget->bbNum); bTarget->SetFlags(BBF_HAS_LABEL); @@ -5564,17 +5564,16 @@ unsigned CodeGen::genEmitJumpTable(GenTree* treeNode, bool relativeAddr) noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH)); assert(treeNode->OperIs(GT_JMPTABLE)); - emitter* emit = GetEmitter(); - const unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab; - const unsigned jmpTabBase = emit->emitBBTableDataGenBeg(jumpCount, relativeAddr); + emitter* emit = GetEmitter(); + const unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->GetCaseCount(); + FlowEdge** const jumpTable = compiler->compCurBB->GetSwitchTargets()->GetCases(); + const unsigned jmpTabBase = emit->emitBBTableDataGenBeg(jumpCount, relativeAddr); JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase); for (unsigned i = 0; i < jumpCount; i++) { - BasicBlock* target = (*jumpTable)->getDestinationBlock(); - jumpTable++; + BasicBlock* target = jumpTable[i]->getDestinationBlock(); noway_assert(target->HasFlag(BBF_HAS_LABEL)); JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum); diff --git a/src/runtime/src/coreclr/jit/compiler.h b/src/runtime/src/coreclr/jit/compiler.h index d30efd26a5e..70cca1ec6ca 100644 --- a/src/runtime/src/coreclr/jit/compiler.h +++ b/src/runtime/src/coreclr/jit/compiler.h @@ -6028,45 +6028,6 @@ class Compiler PhaseStatus fgInsertGCPolls(); BasicBlock* fgCreateGCPoll(GCPollType pollType, BasicBlock* block); -public: - // For many purposes, it is desirable to be able to enumerate the *distinct* targets of a switch statement, - // skipping duplicate targets. (E.g., in flow analyses that are only interested in the set of possible targets.) - // SwitchUniqueSuccSet contains the non-duplicated switch successor edges. - // Code that modifies the flowgraph (such as by renumbering blocks) must call Compiler::InvalidateUniqueSwitchSuccMap, - // and code that modifies the targets of a switch block must call Compiler::fgInvalidateSwitchDescMapEntry. - // If the unique targets of a switch block are needed later, they will be recomputed, ensuring they're up-to-date. - struct SwitchUniqueSuccSet - { - unsigned numDistinctSuccs; // Number of distinct targets of the switch. - FlowEdge** nonDuplicates; // Array of "numDistinctSuccs", containing all the distinct switch target - // successor edges. - }; - - typedef JitHashTable, SwitchUniqueSuccSet> BlockToSwitchDescMap; - -private: - // Maps BasicBlock*'s that end in switch statements to SwitchUniqueSuccSets that allow - // iteration over only the distinct successors. - BlockToSwitchDescMap* m_switchDescMap = nullptr; - -public: - BlockToSwitchDescMap* GetSwitchDescMap(bool createIfNull = true) - { - if ((m_switchDescMap == nullptr) && createIfNull) - { - m_switchDescMap = new (getAllocator()) BlockToSwitchDescMap(getAllocator()); - } - return m_switchDescMap; - } - - SwitchUniqueSuccSet GetDescriptorForSwitch(BasicBlock* switchBlk); - - bool GetDescriptorForSwitchIfAvailable(BasicBlock* switchBlk, SwitchUniqueSuccSet* res); - - void fgRemoveSuccFromSwitchDescMapEntry(BasicBlock* switchBlk, FlowEdge* edge); - - void fgInvalidateSwitchDescMapEntry(BasicBlock* switchBlk); - BasicBlock* fgFirstBlockOfHandler(BasicBlock* block); FlowEdge* fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred); diff --git a/src/runtime/src/coreclr/jit/compiler.hpp b/src/runtime/src/coreclr/jit/compiler.hpp index 38c092ebfa2..0261b272181 100644 --- a/src/runtime/src/coreclr/jit/compiler.hpp +++ b/src/runtime/src/coreclr/jit/compiler.hpp @@ -663,9 +663,9 @@ BasicBlockVisit BasicBlock::VisitAllSuccs(Compiler* comp, TFunc func, const bool // LEAVE into callfinally yet, and haven't added return successors. if (bbEhfTargets != nullptr) { - for (unsigned i = 0; i < bbEhfTargets->bbeCount; i++) + for (unsigned i = 0; i < bbEhfTargets->GetSuccCount(); i++) { - RETURN_ON_ABORT(func(bbEhfTargets->bbeSuccs[i]->getDestinationBlock())); + RETURN_ON_ABORT(func(bbEhfTargets->GetSucc(i)->getDestinationBlock())); } } @@ -711,10 +711,9 @@ BasicBlockVisit BasicBlock::VisitAllSuccs(Compiler* comp, TFunc func, const bool case BBJ_SWITCH: { - Compiler::SwitchUniqueSuccSet sd = comp->GetDescriptorForSwitch(this); - for (unsigned i = 0; i < sd.numDistinctSuccs; i++) + for (unsigned i = 0; i < bbSwtTargets->GetSuccCount(); i++) { - RETURN_ON_ABORT(func(sd.nonDuplicates[i]->getDestinationBlock())); + RETURN_ON_ABORT(func(bbSwtTargets->GetSucc(i)->getDestinationBlock())); } return VisitEHSuccs(comp, func); @@ -750,9 +749,9 @@ BasicBlockVisit BasicBlock::VisitRegularSuccs(Compiler* comp, TFunc func) // LEAVE into callfinally yet, and haven't added return successors. if (bbEhfTargets != nullptr) { - for (unsigned i = 0; i < bbEhfTargets->bbeCount; i++) + for (unsigned i = 0; i < bbEhfTargets->GetSuccCount(); i++) { - RETURN_ON_ABORT(func(bbEhfTargets->bbeSuccs[i]->getDestinationBlock())); + RETURN_ON_ABORT(func(bbEhfTargets->GetSucc(i)->getDestinationBlock())); } } @@ -778,10 +777,9 @@ BasicBlockVisit BasicBlock::VisitRegularSuccs(Compiler* comp, TFunc func) case BBJ_SWITCH: { - Compiler::SwitchUniqueSuccSet sd = comp->GetDescriptorForSwitch(this); - for (unsigned i = 0; i < sd.numDistinctSuccs; i++) + for (unsigned i = 0; i < bbSwtTargets->GetSuccCount(); i++) { - RETURN_ON_ABORT(func(sd.nonDuplicates[i]->getDestinationBlock())); + RETURN_ON_ABORT(func(bbSwtTargets->GetSucc(i)->getDestinationBlock())); } return BasicBlockVisit::Continue; diff --git a/src/runtime/src/coreclr/jit/emitarm64sve.cpp b/src/runtime/src/coreclr/jit/emitarm64sve.cpp index 9d0fe49fbc0..25f1817ae45 100644 --- a/src/runtime/src/coreclr/jit/emitarm64sve.cpp +++ b/src/runtime/src/coreclr/jit/emitarm64sve.cpp @@ -5436,7 +5436,7 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, assert(isVectorRegister(reg2)); // nnnnn assert(isLowVectorRegister(reg3)); // mmmm - if (opt == INS_OPTS_SCALABLE_H) + if (opt == INS_OPTS_SCALABLE_S) { assert((REG_V0 <= reg3) && (reg3 <= REG_V7)); // mmm assert(isValidUimm<3>(imm)); // ii i @@ -5444,7 +5444,7 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, } else { - assert(opt == INS_OPTS_SCALABLE_S); + assert(opt == INS_OPTS_SCALABLE_D); assert(isValidUimm<2>(imm)); // i i fmt = IF_SVE_FE_3B; } @@ -5463,7 +5463,7 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, assert(isVectorRegister(reg2)); // nnnnn assert(isLowVectorRegister(reg3)); // mmmm - if (opt == INS_OPTS_SCALABLE_H) + if (opt == INS_OPTS_SCALABLE_S) { assert((REG_V0 <= reg3) && (reg3 <= REG_V7)); // mmm assert(isValidUimm<3>(imm)); // ii i @@ -5471,7 +5471,7 @@ void emitter::emitInsSve_R_R_R_I(instruction ins, } else { - assert(opt == INS_OPTS_SCALABLE_S); + assert(opt == INS_OPTS_SCALABLE_D); assert(isValidUimm<2>(imm)); // i i fmt = IF_SVE_FG_3B; } @@ -12999,7 +12999,7 @@ void emitter::emitInsSveSanityCheck(instrDesc* id) case IF_SVE_FG_3B: // ...........immmm ....i.nnnnnddddd -- SVE2 integer multiply-add long (indexed) case IF_SVE_FH_3B: // ...........immmm ....i.nnnnnddddd -- SVE2 saturating multiply (indexed) case IF_SVE_FJ_3B: // ...........immmm ....i.nnnnnddddd -- SVE2 saturating multiply-add (indexed) - assert(id->idInsOpt() == INS_OPTS_SCALABLE_S); + assert(id->idInsOpt() == INS_OPTS_SCALABLE_D); assert(isVectorRegister(id->idReg1())); // ddddd assert(isVectorRegister(id->idReg2())); // nnnnn assert(isLowVectorRegister(id->idReg3())); // mmmm diff --git a/src/runtime/src/coreclr/jit/fgbasic.cpp b/src/runtime/src/coreclr/jit/fgbasic.cpp index e6e11155230..4a8a1edb3f1 100644 --- a/src/runtime/src/coreclr/jit/fgbasic.cpp +++ b/src/runtime/src/coreclr/jit/fgbasic.cpp @@ -183,6 +183,12 @@ void Compiler::fgConvertBBToThrowBB(BasicBlock* block) // Update jump kind after the scrub. block->SetKindAndTargetEdge(BBJ_THROW); block->RemoveFlags(BBF_RETLESS_CALL); // no longer a BBJ_CALLFINALLY + + // Heuristic: Throw blocks without profile-derived weights are presumed to be rare. + if (!block->hasProfileWeight()) + { + block->bbSetRunRarely(); + } } /***************************************************************************** @@ -204,42 +210,15 @@ void Compiler::fgChangeSwitchBlock(BasicBlock* oldSwitchBlock, BasicBlock* newSw // Walk the switch's jump table, updating the predecessor for each branch. BBswtDesc* swtDesc = oldSwitchBlock->GetSwitchTargets(); - for (unsigned i = 0; i < swtDesc->bbsCount; i++) + for (unsigned i = 0; i < swtDesc->GetSuccCount(); i++) { - FlowEdge* succEdge = swtDesc->bbsDstTab[i]; - assert(succEdge != nullptr); + FlowEdge* succEdge = swtDesc->GetSucc(i); + assert(succEdge->getSourceBlock() == oldSwitchBlock); - if (succEdge->getSourceBlock() != oldSwitchBlock) - { - // swtDesc can have duplicate targets, so we may have updated this edge already - // - assert(succEdge->getSourceBlock() == newSwitchBlock); - assert(succEdge->getDupCount() > 1); - } - else - { - // Redirect edge's source block from oldSwitchBlock to newSwitchBlock, - // and keep successor block's pred list in order - // - fgReplacePred(succEdge, newSwitchBlock); - } - } - - if (m_switchDescMap != nullptr) - { - SwitchUniqueSuccSet uniqueSuccSet; - - // If already computed and cached the unique descriptors for the old block, let's - // update those for the new block. - if (m_switchDescMap->Lookup(oldSwitchBlock, &uniqueSuccSet)) - { - m_switchDescMap->Set(newSwitchBlock, uniqueSuccSet, BlockToSwitchDescMap::Overwrite); - } - else - { - fgInvalidateSwitchDescMapEntry(newSwitchBlock); - } - fgInvalidateSwitchDescMapEntry(oldSwitchBlock); + // Redirect edge's source block from oldSwitchBlock to newSwitchBlock, + // and keep successor block's pred list in order + // + fgReplacePred(succEdge, newSwitchBlock); } } @@ -259,11 +238,11 @@ void Compiler::fgChangeEhfBlock(BasicBlock* oldBlock, BasicBlock* newBlock) assert(oldBlock->KindIs(BBJ_EHFINALLYRET)); assert(fgPredsComputed); - BBehfDesc* ehfDesc = oldBlock->GetEhfTargets(); + BBJumpTable* ehfDesc = oldBlock->GetEhfTargets(); - for (unsigned i = 0; i < ehfDesc->bbeCount; i++) + for (unsigned i = 0; i < ehfDesc->GetSuccCount(); i++) { - FlowEdge* succEdge = ehfDesc->bbeSuccs[i]; + FlowEdge* succEdge = ehfDesc->GetSucc(i); fgReplacePred(succEdge, newBlock); } } @@ -288,9 +267,9 @@ void Compiler::fgReplaceEhfSuccessor(BasicBlock* block, BasicBlock* oldSucc, Bas assert(block->KindIs(BBJ_EHFINALLYRET)); assert(fgPredsComputed); - BBehfDesc* const ehfDesc = block->GetEhfTargets(); - const unsigned succCount = ehfDesc->bbeCount; - FlowEdge** const succTab = ehfDesc->bbeSuccs; + BBJumpTable* const ehfDesc = block->GetEhfTargets(); + const unsigned succCount = ehfDesc->GetSuccCount(); + FlowEdge** const succTab = ehfDesc->GetSuccs(); // Walk the successor table looking for the old successor, which we expect to find only once. unsigned oldSuccNum = UINT_MAX; @@ -344,48 +323,38 @@ void Compiler::fgReplaceEhfSuccessor(BasicBlock* block, BasicBlock* oldSucc, Bas // // Arguments: // block - BBJ_EHFINALLYRET block -// succIndex - index of the successor in block->GetEhfTargets()->bbeSuccs +// succIndex - index of the successor in the block's jump table // void Compiler::fgRemoveEhfSuccFromTable(BasicBlock* block, const unsigned succIndex) { assert(block != nullptr); assert(block->KindIs(BBJ_EHFINALLYRET)); - BBehfDesc* const ehfDesc = block->GetEhfTargets(); - const unsigned succCount = ehfDesc->bbeCount; - FlowEdge** succTab = ehfDesc->bbeSuccs; - assert(succIndex < succCount); - FlowEdge* const succEdge = succTab[succIndex]; - - // If succEdge is not the last entry, move everything after in the table down one slot. - if ((succIndex + 1) < succCount) - { - memmove_s(&succTab[succIndex], (succCount - succIndex) * sizeof(FlowEdge*), &succTab[succIndex + 1], - (succCount - succIndex - 1) * sizeof(FlowEdge*)); - } + BBJumpTable* const ehfDesc = block->GetEhfTargets(); + FlowEdge* const succEdge = ehfDesc->GetSucc(succIndex); + ehfDesc->RemoveSucc(succIndex); // Recompute the likelihoods of the block's other successor edges. const weight_t removedLikelihood = succEdge->getLikelihood(); - const unsigned newSuccCount = succCount - 1; + const unsigned newSuccCount = ehfDesc->GetSuccCount(); for (unsigned i = 0; i < newSuccCount; i++) { // If we removed all of the flow out of 'block', distribute flow among the remaining edges evenly. - const weight_t currLikelihood = succTab[i]->getLikelihood(); - const weight_t newLikelihood = + FlowEdge* const edge = ehfDesc->GetSucc(i); + const weight_t currLikelihood = edge->getLikelihood(); + const weight_t newLikelihood = (removedLikelihood == 1.0) ? (1.0 / newSuccCount) : (currLikelihood / (1.0 - removedLikelihood)); - succTab[i]->setLikelihood(min(1.0, newLikelihood)); + edge->setLikelihood(min(1.0, newLikelihood)); } #ifdef DEBUG // We only expect to see a successor once in the table. - for (unsigned i = succIndex; i < (succCount - 1); i++) + for (unsigned i = succIndex; i < newSuccCount; i++) { - assert(succTab[i]->getDestinationBlock() != succEdge->getDestinationBlock()); + assert(ehfDesc->GetSucc(i)->getDestinationBlock() != succEdge->getDestinationBlock()); } #endif // DEBUG - - ehfDesc->bbeCount--; } //------------------------------------------------------------------------ @@ -407,50 +376,18 @@ void Compiler::fgRemoveEhfSuccessor(FlowEdge* succEdge) fgRemoveRefPred(succEdge); - BBehfDesc* const ehfDesc = block->GetEhfTargets(); - const unsigned succCount = ehfDesc->bbeCount; - FlowEdge** succTab = ehfDesc->bbeSuccs; - bool found = false; + BBJumpTable* const ehfDesc = block->GetEhfTargets(); - // Search succTab for succEdge so we can splice it out of the table. - for (unsigned i = 0; i < succCount; i++) + for (unsigned i = 0; i < ehfDesc->GetSuccCount(); i++) { - if (succTab[i] == succEdge) + if (ehfDesc->GetSucc(i) == succEdge) { - // If succEdge not the last entry, move everything after in the table down one slot. - if ((i + 1) < succCount) - { - memmove_s(&succTab[i], (succCount - i) * sizeof(FlowEdge*), &succTab[i + 1], - (succCount - i - 1) * sizeof(FlowEdge*)); - } - - found = true; - -#ifdef DEBUG - // We only expect to see a successor once in the table. - for (; i < (succCount - 1); i++) - { - assert(succTab[i]->getDestinationBlock() != succEdge->getDestinationBlock()); - } -#endif // DEBUG + fgRemoveEhfSuccFromTable(block, i); + return; } } - // Recompute the likelihoods of the block's other successor edges. - const weight_t removedLikelihood = succEdge->getLikelihood(); - const unsigned newSuccCount = succCount - 1; - - for (unsigned i = 0; i < newSuccCount; i++) - { - // If we removed all of the flow out of 'block', distribute flow among the remaining edges evenly. - const weight_t currLikelihood = succTab[i]->getLikelihood(); - const weight_t newLikelihood = - (removedLikelihood == 1.0) ? (1.0 / newSuccCount) : (currLikelihood / (1.0 - removedLikelihood)); - succTab[i]->setLikelihood(min(1.0, newLikelihood)); - } - - assert(found); - ehfDesc->bbeCount--; + unreached(); } //------------------------------------------------------------------------ @@ -510,8 +447,8 @@ void Compiler::fgReplaceJumpTarget(BasicBlock* block, BasicBlock* oldTarget, Bas case BBJ_SWITCH: { - unsigned const jumpCnt = block->GetSwitchTargets()->bbsCount; - FlowEdge** const jumpTab = block->GetSwitchTargets()->bbsDstTab; + unsigned const jumpCnt = block->GetSwitchTargets()->GetCaseCount(); + FlowEdge** const jumpTab = block->GetSwitchTargets()->GetCases(); FlowEdge* oldEdge = nullptr; FlowEdge* newEdge = nullptr; bool changed = false; @@ -562,8 +499,15 @@ void Compiler::fgReplaceJumpTarget(BasicBlock* block, BasicBlock* oldTarget, Bas assert(newEdge->getDestinationBlock() == newTarget); newEdge->addLikelihood(oldEdge->getLikelihood()); - // Remove 'oldEdge' from the switch map entry, if it exists. - fgRemoveSuccFromSwitchDescMapEntry(block, oldEdge); + for (unsigned i = block->GetSwitchTargets()->GetSuccCount(); i != 0; i--) + { + if (block->GetSwitchTargets()->GetSucc(i - 1) == oldEdge) + { + // Remove the old edge from the unique successor table. + block->GetSwitchTargets()->RemoveSucc(i - 1); + break; + } + } } // If we simply redirected 'oldEdge' to 'newTarget', we don't need to update the switch map entry, @@ -2876,26 +2820,34 @@ void Compiler::fgLinkBasicBlocks() case BBJ_SWITCH: { - const unsigned numSucc = curBBdesc->GetSwitchTargets()->bbsCount; - unsigned jumpCnt = numSucc; - FlowEdge** jumpPtr = curBBdesc->GetSwitchTargets()->bbsDstTab; + const unsigned numCases = curBBdesc->GetSwitchTargets()->GetCaseCount(); + FlowEdge** const cases = curBBdesc->GetSwitchTargets()->GetCases(); + FlowEdge** const succs = cases - numCases; + unsigned numUnique = 0; - do + for (unsigned i = 0; i < numCases; i++) { - BasicBlock* jumpDest = fgLookupBB((unsigned)*(size_t*)jumpPtr); + BasicBlock* jumpDest = fgLookupBB((unsigned)*(size_t*)(cases + i)); FlowEdge* const newEdge = fgAddRefPred(jumpDest, curBBdesc); - newEdge->setLikelihood((1.0 / numSucc) * newEdge->getDupCount()); - *jumpPtr = newEdge; - if (jumpDest->bbNum <= curBBdesc->bbNum) + newEdge->setLikelihood((1.0 / numCases) * newEdge->getDupCount()); + cases[i] = newEdge; + + if (newEdge->getDupCount() == 1) { - fgMarkBackwardJump(jumpDest, curBBdesc); + succs[numUnique++] = newEdge; + if (jumpDest->bbNum <= curBBdesc->bbNum) + { + fgMarkBackwardJump(jumpDest, curBBdesc); + } } - } while (++jumpPtr, --jumpCnt); + } - /* Default case of CEE_SWITCH (next block), is at end of jumpTab[] */ + curBBdesc->GetSwitchTargets()->SetSuccs(succs, numUnique); - noway_assert(curBBdesc->NextIs((*(jumpPtr - 1))->getDestinationBlock())); + /* Default case of CEE_SWITCH (next block), is at end of cases[] */ + + noway_assert(curBBdesc->NextIs(cases[numCases - 1]->getDestinationBlock())); break; } @@ -3054,56 +3006,42 @@ void Compiler::fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed case CEE_SWITCH: { - unsigned jmpBase; - unsigned jmpCnt; // # of switch cases (excluding default) - - FlowEdge** jmpTab; - FlowEdge** jmpPtr; - - /* Allocate the switch descriptor */ - - swtDsc = new (this, CMK_BasicBlock) BBswtDesc; - /* Read the number of entries in the table */ - jmpCnt = getU4LittleEndian(codeAddr); + const unsigned jmpCnt = getU4LittleEndian(codeAddr); // # of switch cases (excluding default) codeAddr += 4; /* Compute the base offset for the opcode */ - jmpBase = (IL_OFFSET)((codeAddr - codeBegp) + jmpCnt * sizeof(DWORD)); + const unsigned jmpBase = (IL_OFFSET)((codeAddr - codeBegp) + jmpCnt * sizeof(DWORD)); - /* Allocate the jump table */ + /* Allocate the jump table, ensuring there's space for all cases, the default case, and unique succs */ - jmpPtr = jmpTab = new (this, CMK_FlowEdge) FlowEdge*[jmpCnt + 1]; + FlowEdge** const jmpTab = new (this, CMK_FlowEdge) FlowEdge*[(jmpCnt + 1) * 2]; + FlowEdge** const cases = jmpTab + (jmpCnt + 1); /* Fill in the jump table */ - for (unsigned count = jmpCnt; count; count--) + for (unsigned i = 0; i < jmpCnt; i++) { jmpDist = getI4LittleEndian(codeAddr); codeAddr += 4; // store the offset in the pointer. We change these in fgLinkBasicBlocks(). - *jmpPtr++ = (FlowEdge*)(size_t)(jmpBase + jmpDist); + cases[i] = (FlowEdge*)(size_t)(jmpBase + jmpDist); } /* Append the default label to the target table */ - *jmpPtr++ = (FlowEdge*)(size_t)jmpBase; - - /* Make sure we found the right number of labels */ - - noway_assert(jmpPtr == jmpTab + jmpCnt + 1); + cases[jmpCnt] = (FlowEdge*)(size_t)jmpBase; /* Compute the size of the switch opcode operands */ sz = sizeof(DWORD) + jmpCnt * sizeof(DWORD); - /* Fill in the remaining fields of the switch descriptor */ + /* Allocate the switch descriptor; we will initialize the unique successors in fgLinkBasicBlocks */ - swtDsc->bbsCount = jmpCnt + 1; - swtDsc->bbsDstTab = jmpTab; + swtDsc = new (this, CMK_BasicBlock) BBswtDesc(nullptr, 0, cases, jmpCnt + 1, true); /* This is definitely a jump */ @@ -4240,7 +4178,7 @@ void Compiler::fgCheckBasicBlockControlFlow() break; case BBJ_SWITCH: // block ends with a switch statement - for (BasicBlock* const bTarget : blk->SwitchTargets()) + for (BasicBlock* const bTarget : blk->SwitchSuccs()) { fgControlFlowPermitted(blk, bTarget); } diff --git a/src/runtime/src/coreclr/jit/fgdiagnostic.cpp b/src/runtime/src/coreclr/jit/fgdiagnostic.cpp index 50145f04b32..9cbc76ceb77 100644 --- a/src/runtime/src/coreclr/jit/fgdiagnostic.cpp +++ b/src/runtime/src/coreclr/jit/fgdiagnostic.cpp @@ -1068,7 +1068,7 @@ bool Compiler::fgDumpFlowGraph(Phases phase, PhasePosition pos) { fprintf(fgxFile, "\n switchCases=\"%d\"", edge->getDupCount()); } - if (bSource->GetSwitchTargets()->getDefault()->getDestinationBlock() == bTarget) + if (bSource->GetSwitchTargets()->GetDefaultCase()->getDestinationBlock() == bTarget) { fprintf(fgxFile, "\n switchDefault=\"true\""); } @@ -1978,7 +1978,7 @@ void Compiler::fgTableDispBasicBlock(const BasicBlock* block, printf("->"); printedBlockWidth = 2 + 9 /* kind */; - const BBehfDesc* const ehfDesc = block->GetEhfTargets(); + const BBJumpTable* const ehfDesc = block->GetEhfTargets(); if (ehfDesc == nullptr) { printf(" ????"); @@ -1988,13 +1988,10 @@ void Compiler::fgTableDispBasicBlock(const BasicBlock* block, { // Very early in compilation, we won't have fixed up the BBJ_EHFINALLYRET successors yet. - const unsigned jumpCnt = ehfDesc->bbeCount; - FlowEdge** const jumpTab = ehfDesc->bbeSuccs; - - for (unsigned i = 0; i < jumpCnt; i++) + for (unsigned i = 0; i < ehfDesc->GetSuccCount(); i++) { printedBlockWidth += 1 /* space/comma */; - printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(jumpTab[i])); + printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(ehfDesc->GetSucc(i))); } } @@ -2040,22 +2037,22 @@ void Compiler::fgTableDispBasicBlock(const BasicBlock* block, printedBlockWidth = 2 + 9 /* kind */; const BBswtDesc* const jumpSwt = block->GetSwitchTargets(); - const unsigned jumpCnt = jumpSwt->bbsCount; - FlowEdge** const jumpTab = jumpSwt->bbsDstTab; + const unsigned jumpCnt = jumpSwt->GetCaseCount(); + FlowEdge** const jumpTab = jumpSwt->GetCases(); for (unsigned i = 0; i < jumpCnt; i++) { printedBlockWidth += 1 /* space/comma */; printf("%c%s", (i == 0) ? ' ' : ',', dspBlockNum(jumpTab[i])); - const bool isDefault = jumpSwt->bbsHasDefault && (i == jumpCnt - 1); + const bool isDefault = jumpSwt->HasDefaultCase() && (i == jumpCnt - 1); if (isDefault) { printf("[def]"); printedBlockWidth += 5; } - const bool isDominant = jumpSwt->bbsHasDominantCase && (i == jumpSwt->bbsDominantCase); + const bool isDominant = jumpSwt->HasDominantCase() && (i == jumpSwt->GetDominantCase()); if (isDominant) { printf("[dom]"); @@ -2786,7 +2783,7 @@ bool BBPredsChecker::CheckJump(BasicBlock* blockPred, BasicBlock* block) break; case BBJ_SWITCH: - for (BasicBlock* const bTarget : blockPred->SwitchTargets()) + for (BasicBlock* const bTarget : blockPred->SwitchSuccs()) { if (block == bTarget) { @@ -2970,38 +2967,10 @@ void Compiler::fgDebugCheckBBlist(bool checkBBNum /* = false */, bool checkBBRef maxBBNum = max(maxBBNum, block->bbNum); - // Check that all the successors have the current traversal stamp. Use the 'Compiler*' version of the - // iterator, but not for BBJ_SWITCH: we don't want to end up calling GetDescriptorForSwitch(), which will - // dynamically create the unique switch list. - if (block->KindIs(BBJ_SWITCH)) + // Check that all the successors have the current traversal stamp. + for (BasicBlock* const succBlock : block->Succs(this)) { - for (BasicBlock* const succBlock : block->Succs()) - { - assert(succBlock->bbTraversalStamp == curTraversalStamp); - } - - // Also check the unique successor set, if it exists. Make sure to NOT allocate it if it doesn't exist! - BlockToSwitchDescMap* switchMap = GetSwitchDescMap(/* createIfNull */ false); - if (switchMap != nullptr) - { - SwitchUniqueSuccSet sd; - if (switchMap->Lookup(block, &sd)) - { - for (unsigned i = 0; i < sd.numDistinctSuccs; i++) - { - const BasicBlock* const nonDuplicateSucc = sd.nonDuplicates[i]->getDestinationBlock(); - assert(nonDuplicateSucc != nullptr); - assert(nonDuplicateSucc->bbTraversalStamp == curTraversalStamp); - } - } - } - } - else - { - for (BasicBlock* const succBlock : block->Succs(this)) - { - assert(succBlock->bbTraversalStamp == curTraversalStamp); - } + assert(succBlock->bbTraversalStamp == curTraversalStamp); } // If the block is a BBJ_COND, a BBJ_SWITCH or a @@ -3971,31 +3940,24 @@ void Compiler::fgDebugCheckBlockLinks() } // If this is a switch, check that the tables are consistent. - // Note that we don't call GetSwitchDescMap(), because it has the side-effect - // of allocating it if it is not present. - if (block->KindIs(BBJ_SWITCH) && m_switchDescMap != nullptr) + if (block->KindIs(BBJ_SWITCH)) { - SwitchUniqueSuccSet uniqueSuccSet; - if (m_switchDescMap->Lookup(block, &uniqueSuccSet)) + // Create a set with all the successors. + BitVecTraits bitVecTraits(fgBBNumMax + 1, this); + BitVec succBlocks(BitVecOps::MakeEmpty(&bitVecTraits)); + for (unsigned i = 0; i < block->GetSwitchTargets()->GetCaseCount(); i++) { - // Create a set with all the successors. Don't use BlockSet, so we don't need to worry - // about the BlockSet epoch. - BitVecTraits bitVecTraits(fgBBNumMax + 1, this); - BitVec succBlocks(BitVecOps::MakeEmpty(&bitVecTraits)); - for (BasicBlock* const bTarget : block->SwitchTargets()) - { - BitVecOps::AddElemD(&bitVecTraits, succBlocks, bTarget->bbNum); - } - // Now we should have a set of unique successors that matches what's in the switchMap. - // First, check the number of entries, then make sure all the blocks in uniqueSuccSet - // are in the BlockSet. - unsigned count = BitVecOps::Count(&bitVecTraits, succBlocks); - assert(uniqueSuccSet.numDistinctSuccs == count); - for (unsigned i = 0; i < uniqueSuccSet.numDistinctSuccs; i++) - { - assert(BitVecOps::IsMember(&bitVecTraits, succBlocks, - uniqueSuccSet.nonDuplicates[i]->getDestinationBlock()->bbNum)); - } + BasicBlock* const bTarget = block->GetSwitchTargets()->GetCase(i)->getDestinationBlock(); + BitVecOps::AddElemD(&bitVecTraits, succBlocks, bTarget->bbNum); + } + // Now we should have a set of unique successors that matches what's in the switchMap. + // First, check the number of entries, then make sure all the blocks in the unique successor table + // match the blocks in the set. + unsigned count = BitVecOps::Count(&bitVecTraits, succBlocks); + assert(block->GetSwitchTargets()->GetSuccCount() == count); + for (BasicBlock* const bTarget : block->SwitchSuccs()) + { + assert(BitVecOps::IsMember(&bitVecTraits, succBlocks, bTarget->bbNum)); } } } diff --git a/src/runtime/src/coreclr/jit/fgehopt.cpp b/src/runtime/src/coreclr/jit/fgehopt.cpp index 084afc58468..ceb5d7c12a2 100644 --- a/src/runtime/src/coreclr/jit/fgehopt.cpp +++ b/src/runtime/src/coreclr/jit/fgehopt.cpp @@ -1607,7 +1607,7 @@ PhaseStatus Compiler::fgCloneFinally() { if (block->KindIs(BBJ_EHFINALLYRET)) { - assert(block->GetEhfTargets()->bbeCount == 0); + assert(block->GetEhfTargets()->GetSuccCount() == 0); block->SetKind(BBJ_EHFAULTRET); } } diff --git a/src/runtime/src/coreclr/jit/fgflow.cpp b/src/runtime/src/coreclr/jit/fgflow.cpp index f7a055f4a76..c22bde11ea5 100644 --- a/src/runtime/src/coreclr/jit/fgflow.cpp +++ b/src/runtime/src/coreclr/jit/fgflow.cpp @@ -307,10 +307,10 @@ void Compiler::fgRemoveBlockAsPred(BasicBlock* block) case BBJ_EHFINALLYRET: { - BBehfDesc* const ehfDesc = block->GetEhfTargets(); - for (unsigned i = 0; i < ehfDesc->bbeCount; i++) + BBJumpTable* const ehfDesc = block->GetEhfTargets(); + for (unsigned i = 0; i < ehfDesc->GetSuccCount(); i++) { - fgRemoveRefPred(ehfDesc->bbeSuccs[i]); + fgRemoveAllRefPreds(ehfDesc->GetSucc(i)->getDestinationBlock(), block); } break; } @@ -323,9 +323,9 @@ void Compiler::fgRemoveBlockAsPred(BasicBlock* block) case BBJ_SWITCH: { BBswtDesc* const swtDesc = block->GetSwitchTargets(); - for (unsigned i = 0; i < swtDesc->bbsCount; i++) + for (unsigned i = 0; i < swtDesc->GetSuccCount(); i++) { - fgRemoveRefPred(swtDesc->bbsDstTab[i]); + fgRemoveAllRefPreds(swtDesc->GetSucc(i)->getDestinationBlock(), block); } break; } @@ -404,142 +404,3 @@ void Compiler::fgRedirectEdge(FlowEdge*& edge, BasicBlock* newTarget) // Pred list of target should still be ordered assert(newTarget->checkPredListOrder()); } - -//------------------------------------------------------------------------ -// GetDescriptorForSwitch: Returns the SwitchUniqueSuccSet corresponding to 'switchBlk'. -// If it does not exist in the map yet, we build and insert the entry. -// -// Arguments: -// switchBlk -- The switch block -// -// Returns: -// The SwitchUniqueSuccSet corresponding to 'switchBlk' -// -Compiler::SwitchUniqueSuccSet Compiler::GetDescriptorForSwitch(BasicBlock* switchBlk) -{ - assert(switchBlk->KindIs(BBJ_SWITCH)); - BlockToSwitchDescMap* switchMap = GetSwitchDescMap(); - SwitchUniqueSuccSet res; - if (switchMap->Lookup(switchBlk, &res)) - { - return res; - } - else - { - // We must compute the descriptor. Find which are dups, by creating a bit set with the unique successors. - // We create a temporary bitset of blocks to compute the unique set of successor blocks, - // since adding a block's number twice leaves just one "copy" in the bitset. - - BitVecTraits blockVecTraits(fgBBNumMax + 1, this); - BitVec uniqueSuccBlocks(BitVecOps::MakeEmpty(&blockVecTraits)); - for (BasicBlock* const targ : switchBlk->SwitchTargets()) - { - BitVecOps::AddElemD(&blockVecTraits, uniqueSuccBlocks, targ->bbNum); - } - // Now we have a set of unique successors. - unsigned numNonDups = BitVecOps::Count(&blockVecTraits, uniqueSuccBlocks); - - FlowEdge** nonDups = new (getAllocator()) FlowEdge*[numNonDups]; - - unsigned nonDupInd = 0; - - // At this point, all unique targets are in "uniqueSuccBlocks". As we encounter each, - // add to nonDups, remove from "uniqueSuccBlocks". - BBswtDesc* const swtDesc = switchBlk->GetSwitchTargets(); - for (unsigned i = 0; i < swtDesc->bbsCount; i++) - { - FlowEdge* const succEdge = swtDesc->bbsDstTab[i]; - BasicBlock* const targ = succEdge->getDestinationBlock(); - if (BitVecOps::IsMember(&blockVecTraits, uniqueSuccBlocks, targ->bbNum)) - { - nonDups[nonDupInd] = succEdge; - nonDupInd++; - BitVecOps::RemoveElemD(&blockVecTraits, uniqueSuccBlocks, targ->bbNum); - } - } - - assert(nonDupInd == numNonDups); - assert(BitVecOps::Count(&blockVecTraits, uniqueSuccBlocks) == 0); - res.numDistinctSuccs = numNonDups; - res.nonDuplicates = nonDups; - switchMap->Set(switchBlk, res); - return res; - } -} - -//------------------------------------------------------------------------ -// GetDescriptorForSwitchIfAvailable: Gets the SwitchUniqueSuccSet corresponding to 'switchBlk', -// if it exists. Unlike Compiler::GetDescriptorForSwitch, this will not modify the map. -// -// Arguments: -// switchBlk -- The switch block -// res [out] -- Pointer to the SwitchUniqueSuccSet to populate -// -// Returns: -// True if the map exists, and contains an entry for 'switchBlk' -// -bool Compiler::GetDescriptorForSwitchIfAvailable(BasicBlock* switchBlk, SwitchUniqueSuccSet* res) -{ - assert(switchBlk->KindIs(BBJ_SWITCH)); - return (m_switchDescMap != nullptr) && m_switchDescMap->Lookup(switchBlk, res); -} - -//------------------------------------------------------------------------ -// fgRemoveSuccFromSwitchDescMapEntry: Removes a successor edge from the map entry -// for 'switchBlk', if the entry exists. -// -// Arguments: -// switchBlk -- The switch block -// edge -- The successor edge to remove -// -void Compiler::fgRemoveSuccFromSwitchDescMapEntry(BasicBlock* switchBlk, FlowEdge* edge) -{ - assert(switchBlk->KindIs(BBJ_SWITCH)); - - SwitchUniqueSuccSet uniqueSuccSet; - if (!GetDescriptorForSwitchIfAvailable(switchBlk, &uniqueSuccSet)) - { - return; - } - - const unsigned succCount = uniqueSuccSet.numDistinctSuccs; - FlowEdge** const succTab = uniqueSuccSet.nonDuplicates; - bool found = false; - assert(succCount > 0); - assert(succTab != nullptr); - - for (unsigned i = 0; !found && (i < succCount); i++) - { - if (succTab[i] == edge) - { - // If 'edge' is not the last entry, move everything after in the table down one slot. - if ((i + 1) < succCount) - { - memmove_s(&succTab[i], (succCount - i) * sizeof(FlowEdge*), &succTab[i + 1], - (succCount - i - 1) * sizeof(FlowEdge*)); - } - - found = true; - } - } - - assert(found); - uniqueSuccSet.numDistinctSuccs--; - m_switchDescMap->Set(switchBlk, uniqueSuccSet, BlockToSwitchDescMap::SetKind::Overwrite); -} - -//------------------------------------------------------------------------ -// fgInvalidateSwitchDescMapEntry: Removes the entry for 'block' from the -// switch map, if the map exists. -// -// Arguments: -// block -- The switch block -// -void Compiler::fgInvalidateSwitchDescMapEntry(BasicBlock* block) -{ - // Check if map has no entries yet. - if (m_switchDescMap != nullptr) - { - m_switchDescMap->Remove(block); - } -} diff --git a/src/runtime/src/coreclr/jit/fgopt.cpp b/src/runtime/src/coreclr/jit/fgopt.cpp index 49362517371..252f8eba509 100644 --- a/src/runtime/src/coreclr/jit/fgopt.cpp +++ b/src/runtime/src/coreclr/jit/fgopt.cpp @@ -1588,17 +1588,13 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) { assert(block->KindIs(BBJ_SWITCH)); - unsigned jmpCnt = block->GetSwitchTargets()->bbsCount; - FlowEdge** jmpTab = block->GetSwitchTargets()->bbsDstTab; - BasicBlock* bNewDest; // the new jump target for the current switch case - BasicBlock* bDest; - bool modified = false; + bool modified = false; - do + for (unsigned i = 0; i < block->GetSwitchTargets()->GetSuccCount(); i++) { - REPEAT_SWITCH:; - bDest = (*jmpTab)->getDestinationBlock(); - bNewDest = bDest; + FlowEdge* const edge = block->GetSwitchTargets()->GetSucc(i); + BasicBlock* const bDest = edge->getDestinationBlock(); + BasicBlock* bNewDest = bDest; // Do we have a JUMP to an empty unconditional JUMP block? if (bDest->isEmpty() && bDest->KindIs(BBJ_ALWAYS) && !bDest->TargetIs(bDest)) // special case for self jumps @@ -1616,14 +1612,9 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) if (optimizeJump) { bNewDest = bDest->GetTarget(); -#ifdef DEBUG - if (verbose) - { - printf("\nOptimizing a switch jump to an empty block with an unconditional jump (" FMT_BB - " -> " FMT_BB " -> " FMT_BB ")\n", - block->bbNum, bDest->bbNum, bNewDest->bbNum); - } -#endif // DEBUG + JITDUMP("\nOptimizing a switch jump to an empty block with an unconditional jump (" FMT_BB " -> " FMT_BB + " -> " FMT_BB ")\n", + block->bbNum, bDest->bbNum, bNewDest->bbNum); } } @@ -1633,8 +1624,7 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) // if (bDest->hasProfileWeight()) { - FlowEdge* const oldEdge = *jmpTab; - bDest->decreaseBBProfileWeight(oldEdge->getLikelyWeight()); + bDest->decreaseBBProfileWeight(edge->getLikelyWeight()); } // Redirect the jump to the new target @@ -1642,10 +1632,11 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) fgReplaceJumpTarget(block, bDest, bNewDest); modified = true; - // we optimized a Switch label - goto REPEAT_SWITCH to follow this new jump - goto REPEAT_SWITCH; + // Try optimizing this edge again + // + i--; } - } while (++jmpTab, --jmpCnt); + } if (modified) { @@ -1678,24 +1669,15 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) // At this point all of the case jump targets have been updated such // that none of them go to block that is an empty unconditional block - // - jmpTab = block->GetSwitchTargets()->bbsDstTab; - jmpCnt = block->GetSwitchTargets()->bbsCount; - // Now check for two trivial switch jumps. // - if (block->NumSucc(this) == 1) + if (block->GetSwitchTargets()->GetSuccCount() == 1) { // Use BBJ_ALWAYS for a switch with only a default clause, or with only one unique successor. -#ifdef DEBUG - if (verbose) - { - printf("\nRemoving a switch jump with a single target (" FMT_BB ")\n", block->bbNum); - printf("BEFORE:\n"); - fgDispBasicBlocks(); - } -#endif // DEBUG + JITDUMP("\nRemoving a switch jump with a single target (" FMT_BB ")\n", block->bbNum); + JITDUMP("BEFORE:\n"); + DBEXEC(verbose, fgDispBasicBlocks()); if (block->IsLIR()) { @@ -1765,15 +1747,13 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) } // Change the switch jump into a BBJ_ALWAYS - block->SetKindAndTargetEdge(BBJ_ALWAYS, block->GetSwitchTargets()->bbsDstTab[0]); - for (unsigned i = 1; i < jmpCnt; ++i) - { - fgRemoveRefPred(jmpTab[i]); - } - + block->SetKindAndTargetEdge(BBJ_ALWAYS, block->GetSwitchTargets()->GetCase(0)); + const unsigned dupCount = block->GetTargetEdge()->getDupCount(); + block->GetTargetEdge()->decrementDupCount(dupCount - 1); + block->GetTarget()->bbRefs -= (dupCount - 1); return true; } - else if (block->GetSwitchTargets()->bbsCount == 2) + else if (block->GetSwitchTargets()->GetCaseCount() == 2) { /* Use a BBJ_COND(switchVal==0) for a switch with only one significant clause besides the default clause */ @@ -1795,16 +1775,10 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) // a COMMA node which results in noway asserts in fgMorphSmpOp(), optAssertionGen() and rpPredictTreeRegUse(). // For the same reason fgMorphSmpOp() marks GT_JTRUE nodes with RELOP children as GTF_DONT_CSE. -#ifdef DEBUG - if (verbose) - { - printf("\nConverting a switch (" FMT_BB ") with only one significant clause besides a default target to a " - "conditional branch. Before:\n", - block->bbNum); - - gtDispTree(switchTree); - } -#endif // DEBUG + JITDUMP("\nConverting a switch (" FMT_BB ") with only one significant clause besides a default target to a " + "conditional branch. Before:\n", + block->bbNum); + DISPNODE(switchTree); switchTree->ChangeOper(GT_JTRUE); GenTree* zeroConstNode = gtNewZeroConNode(genActualType(switchVal->TypeGet())); @@ -1824,8 +1798,8 @@ bool Compiler::fgOptimizeSwitchBranches(BasicBlock* block) fgSetStmtSeq(switchStmt); } - FlowEdge* const trueEdge = block->GetSwitchTargets()->bbsDstTab[0]; - FlowEdge* const falseEdge = block->GetSwitchTargets()->bbsDstTab[1]; + FlowEdge* const trueEdge = block->GetSwitchTargets()->GetCase(0); + FlowEdge* const falseEdge = block->GetSwitchTargets()->GetCase(1); block->SetCond(trueEdge, falseEdge); JITDUMP("After:\n"); @@ -2778,7 +2752,7 @@ bool Compiler::fgOptimizeBranch(BasicBlock* bJump) void Compiler::fgPeelSwitch(BasicBlock* block) { assert(block->KindIs(BBJ_SWITCH)); - assert(block->GetSwitchTargets()->bbsHasDominantCase); + assert(block->GetSwitchTargets()->HasDominantCase()); assert(!block->isRunRarely()); // Lowering expands switches, so calling this method on lowered IR @@ -2790,13 +2764,13 @@ void Compiler::fgPeelSwitch(BasicBlock* block) // assert(block->hasProfileWeight()); - const unsigned dominantCase = block->GetSwitchTargets()->bbsDominantCase; + const unsigned dominantCase = block->GetSwitchTargets()->GetDominantCase(); JITDUMP(FMT_BB " has switch with dominant case %u, considering peeling\n", block->bbNum, dominantCase); // The dominant case should not be the default case, as we already peel that one. // - assert(dominantCase < (block->GetSwitchTargets()->bbsCount - 1)); - FlowEdge* const dominantEdge = block->GetSwitchTargets()->bbsDstTab[dominantCase]; + assert(dominantCase < (block->GetSwitchTargets()->GetCaseCount() - 1)); + FlowEdge* const dominantEdge = block->GetSwitchTargets()->GetCase(dominantCase); BasicBlock* const dominantTarget = dominantEdge->getDestinationBlock(); Statement* const switchStmt = block->lastStmt(); GenTree* const switchTree = switchStmt->GetRootNode(); @@ -2856,9 +2830,8 @@ void Compiler::fgPeelSwitch(BasicBlock* block) // and increase all other case likelihoods proportionally. // dominantEdge->setLikelihood(BB_ZERO_WEIGHT); - const SwitchUniqueSuccSet uniqueSuccSet = GetDescriptorForSwitch(newBlock); - const unsigned numSucc = uniqueSuccSet.numDistinctSuccs; - FlowEdge** const jumpTab = uniqueSuccSet.nonDuplicates; + const unsigned numSucc = newBlock->GetSwitchTargets()->GetSuccCount(); + FlowEdge** const jumpTab = newBlock->GetSwitchTargets()->GetSuccs(); for (unsigned i = 0; i < numSucc; i++) { // If we removed all of the flow out of 'block', distribute flow among the remaining edges evenly. @@ -2872,7 +2845,7 @@ void Compiler::fgPeelSwitch(BasicBlock* block) // // But it no longer has a dominant case. // - newBlock->GetSwitchTargets()->bbsHasDominantCase = false; + newBlock->GetSwitchTargets()->RemoveDominantCase(); if (fgNodeThreading == NodeThreading::AllTrees) { diff --git a/src/runtime/src/coreclr/jit/fgprofile.cpp b/src/runtime/src/coreclr/jit/fgprofile.cpp index bafd120b2b8..ff83d3d0e2b 100644 --- a/src/runtime/src/coreclr/jit/fgprofile.cpp +++ b/src/runtime/src/coreclr/jit/fgprofile.cpp @@ -4136,8 +4136,8 @@ void EfficientEdgeCountReconstructor::MarkInterestingSwitches(BasicBlock* block, // If it turns out often we fail at this stage, we might consider building a histogram of switch case // values at runtime, similar to what we do for classes at virtual call sites. // - const unsigned caseCount = block->GetSwitchTargets()->bbsCount; - FlowEdge** const jumpTab = block->GetSwitchTargets()->bbsDstTab; + const unsigned caseCount = block->GetSwitchTargets()->GetCaseCount(); + FlowEdge** const jumpTab = block->GetSwitchTargets()->GetCases(); unsigned dominantCase = caseCount; for (unsigned i = 0; i < caseCount; i++) @@ -4164,7 +4164,7 @@ void EfficientEdgeCountReconstructor::MarkInterestingSwitches(BasicBlock* block, return; } - if (block->GetSwitchTargets()->bbsHasDefault && (dominantCase == caseCount - 1)) + if (block->GetSwitchTargets()->HasDefaultCase() && (dominantCase == caseCount - 1)) { // Dominant case is the default case. // This effectively gets peeled already, so defer. @@ -4178,8 +4178,7 @@ void EfficientEdgeCountReconstructor::MarkInterestingSwitches(BasicBlock* block, "; marking for peeling\n", dominantCase, dominantEdge->m_targetBlock->bbNum, fraction); - block->GetSwitchTargets()->bbsHasDominantCase = true; - block->GetSwitchTargets()->bbsDominantCase = dominantCase; + block->GetSwitchTargets()->SetDominantCase(dominantCase); } //------------------------------------------------------------------------ diff --git a/src/runtime/src/coreclr/jit/flowgraph.cpp b/src/runtime/src/coreclr/jit/flowgraph.cpp index 4db0f7b1ccb..70cfe579923 100644 --- a/src/runtime/src/coreclr/jit/flowgraph.cpp +++ b/src/runtime/src/coreclr/jit/flowgraph.cpp @@ -1290,11 +1290,7 @@ GenTree* Compiler::fgGetCritSectOfStaticMethod() } else { - void *critSect = nullptr, **pCrit = nullptr; - critSect = info.compCompHnd->getMethodSync(info.compMethodHnd, (void**)&pCrit); - noway_assert((!critSect) != (!pCrit)); - - tree = gtNewIconEmbHndNode(critSect, pCrit, GTF_ICON_GLOBAL_PTR, info.compMethodHnd); + tree = gtNewIconEmbClsHndNode(info.compClassHnd); // Given the class handle, get the pointer to the Monitor. tree = gtNewHelperCallNode(CORINFO_HELP_GETSYNCFROMCLASSHANDLE, TYP_REF, tree); diff --git a/src/runtime/src/coreclr/jit/gentree.cpp b/src/runtime/src/coreclr/jit/gentree.cpp index 29682889d4d..6066f4c5c94 100644 --- a/src/runtime/src/coreclr/jit/gentree.cpp +++ b/src/runtime/src/coreclr/jit/gentree.cpp @@ -20737,7 +20737,7 @@ bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, // Some intrinsics are effectively bitwise operations and so we // can freely update them to match the size of the actual mask - bool supportsMaskBaseSize4Or8 = false; + bool supportsMaskBaseSize2Or4 = false; switch (ins) { @@ -20762,13 +20762,13 @@ bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, case INS_xorpd: case INS_xorps: { - // These intrinsics support embedded broadcast and have masking support for 4 or 8 - assert((maskBaseSize == 4) || (maskBaseSize == 8)); + // These intrinsics support embedded broadcast and have masking support for 2 or 4 + assert((maskBaseSize == 2) || (maskBaseSize == 4)); if (!comp->codeGen->IsEmbeddedBroadcastEnabled(ins, node->Op(2))) { // We cannot change the base type if we've already contained a broadcast - supportsMaskBaseSize4Or8 = true; + supportsMaskBaseSize2Or4 = true; } break; } @@ -20776,13 +20776,13 @@ bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, case INS_vpternlogd: case INS_vpternlogq: { - // These intrinsics support embedded broadcast and have masking support for 4 or 8 - assert((maskBaseSize == 4) || (maskBaseSize == 8)); + // These intrinsics support embedded broadcast and have masking support for 2 or 4 + assert((maskBaseSize == 2) || (maskBaseSize == 4)); if (!comp->codeGen->IsEmbeddedBroadcastEnabled(ins, node->Op(3))) { // We cannot change the base type if we've already contained a broadcast - supportsMaskBaseSize4Or8 = true; + supportsMaskBaseSize2Or4 = true; } break; } @@ -20812,9 +20812,9 @@ bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, case INS_vinserti64x2: case INS_vinserti64x4: { - // These intrinsics don't support embedded broadcast and have masking support for 4 or 8 - assert((maskBaseSize == 4) || (maskBaseSize == 8)); - supportsMaskBaseSize4Or8 = true; + // These intrinsics don't support embedded broadcast and have masking support for 2 or 4 + assert((maskBaseSize == 2) || (maskBaseSize == 4)); + supportsMaskBaseSize2Or4 = true; break; } @@ -20824,9 +20824,9 @@ bool GenTree::isEmbeddedMaskingCompatible(Compiler* comp, unsigned tgtMaskSize, } } - if (supportsMaskBaseSize4Or8) + if (supportsMaskBaseSize2Or4) { - if (tgtMaskBaseSize == 8) + if (tgtMaskBaseSize == 2) { if (varTypeIsFloating(simdBaseType)) { @@ -32618,6 +32618,78 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) { switch (ni) { +#if defined(TARGET_ARM64) + case NI_Vector64_ExtractMostSignificantBits: +#elif defined(TARGET_XARCH) + case NI_Vector256_ExtractMostSignificantBits: + case NI_X86Base_MoveMask: + case NI_AVX_MoveMask: + case NI_AVX2_MoveMask: +#endif + case NI_Vector128_ExtractMostSignificantBits: + { + simdmask_t simdMaskVal; + + switch (simdSize) + { + case 8: + { + EvaluateExtractMSB(simdBaseType, &simdMaskVal, cnsNode->AsVecCon()->gtSimd8Val); + break; + } + + case 16: + { + EvaluateExtractMSB(simdBaseType, &simdMaskVal, cnsNode->AsVecCon()->gtSimd16Val); + break; + } + +#if defined(TARGET_XARCH) + case 32: + { + EvaluateExtractMSB(simdBaseType, &simdMaskVal, cnsNode->AsVecCon()->gtSimd32Val); + break; + } +#endif // TARGET_XARCH + + default: + { + unreached(); + } + } + + uint32_t elemCount = simdSize / genTypeSize(simdBaseType); + uint64_t mask = simdMaskVal.GetRawBits() & simdmask_t::GetBitMask(elemCount); + + assert(varTypeIsInt(retType)); + assert(elemCount <= 32); + + resultNode = gtNewIconNode(static_cast(mask)); + break; + } + +#ifdef TARGET_XARCH + case NI_AVX512_MoveMask: + { + GenTreeMskCon* mskCns = cnsNode->AsMskCon(); + + uint32_t elemCount = simdSize / genTypeSize(simdBaseType); + uint64_t mask = mskCns->gtSimdMaskVal.GetRawBits() & simdmask_t::GetBitMask(elemCount); + + if (varTypeIsInt(retType)) + { + assert(elemCount <= 32); + resultNode = gtNewIconNode(static_cast(mask)); + } + else + { + assert(varTypeIsLong(retType)); + resultNode = gtNewLconNode(static_cast(mask)); + } + break; + } +#endif // TARGET_XARCH + #ifdef TARGET_ARM64 case NI_ArmBase_LeadingZeroCount: #else diff --git a/src/runtime/src/coreclr/jit/hwintrinsicarm64.cpp b/src/runtime/src/coreclr/jit/hwintrinsicarm64.cpp index 6631da478c9..18ba7125359 100644 --- a/src/runtime/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/runtime/src/coreclr/jit/hwintrinsicarm64.cpp @@ -299,6 +299,18 @@ void Compiler::getHWIntrinsicImmTypes(NamedIntrinsic intrinsic, } } + if (intrinsic == NI_Sve2_MultiplyBySelectedScalar || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningEven || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningEvenAndAdd || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningOdd || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningOddAndAdd || + intrinsic == NI_Sve2_MultiplyBySelectedScalarWideningOddAndSubtract || + intrinsic == NI_Sve2_MultiplySubtractBySelectedScalar) + { + indexedElementBaseType = simdBaseType; + } + assert(indexedElementBaseType == simdBaseType); } else if (intrinsic == NI_AdvSimd_Arm64_InsertSelectedScalar) @@ -362,14 +374,24 @@ void HWIntrinsicInfo::lookupImmBounds( } else if (category == HW_Category_SIMDByIndexedElement) { - if (intrinsic == NI_Sve_DuplicateSelectedScalarToVector) - { - // For SVE_DUP, the upper bound on index does not depend on the vector length. - immUpperBound = (512 / (BITS_PER_BYTE * genTypeSize(baseType))) - 1; - } - else + switch (intrinsic) { - immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType) - 1; + case NI_Sve_DuplicateSelectedScalarToVector: + // For SVE_DUP, the upper bound on index does not depend on the vector length. + immUpperBound = (512 / (BITS_PER_BYTE * genTypeSize(baseType))) - 1; + break; + case NI_Sve2_MultiplyBySelectedScalarWideningEven: + case NI_Sve2_MultiplyBySelectedScalarWideningEvenAndAdd: + case NI_Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract: + case NI_Sve2_MultiplyBySelectedScalarWideningOdd: + case NI_Sve2_MultiplyBySelectedScalarWideningOddAndAdd: + case NI_Sve2_MultiplyBySelectedScalarWideningOddAndSubtract: + // Index is on the half-width vector, hence double the maximum index. + immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType) * 2 - 1; + break; + default: + immUpperBound = Compiler::getSIMDVectorLength(simdSize, baseType) - 1; + break; } } else @@ -1346,166 +1368,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_ExtractMostSignificantBits: { assert(sig->numArgs == 1); - - // ARM64 doesn't have a single instruction that performs the behavior so we'll emulate it instead. - // To do this, we effectively perform the following steps: - // 1. tmp = input & 0x80 ; and the input to clear all but the most significant bit - // 2. tmp = tmp >> index ; right shift each element by its index - // 3. tmp = sum(tmp) ; sum the elements together - - // For byte/sbyte, we also need to handle the fact that we can only shift by up to 8 - // but for Vector128, we have 16 elements to handle. In that scenario, we will simply - // extract both scalars, and combine them via: (upper << 8) | lower - - var_types simdType = getSIMDTypeForSize(simdSize); - - op1 = impSIMDPopStack(); - - GenTreeVecCon* vecCon2 = gtNewVconNode(simdType); - GenTreeVecCon* vecCon3 = gtNewVconNode(simdType); - - switch (simdBaseType) - { - case TYP_BYTE: - case TYP_UBYTE: - { - simdBaseType = TYP_UBYTE; - simdBaseJitType = CORINFO_TYPE_UBYTE; - - vecCon2->gtSimdVal.u64[0] = 0x8080808080808080; - vecCon3->gtSimdVal.u64[0] = 0x00FFFEFDFCFBFAF9; - - if (simdSize == 16) - { - vecCon2->gtSimdVal.u64[1] = 0x8080808080808080; - vecCon3->gtSimdVal.u64[1] = 0x00FFFEFDFCFBFAF9; - } - break; - } - - case TYP_SHORT: - case TYP_USHORT: - { - simdBaseType = TYP_USHORT; - simdBaseJitType = CORINFO_TYPE_USHORT; - - vecCon2->gtSimdVal.u64[0] = 0x8000800080008000; - vecCon3->gtSimdVal.u64[0] = 0xFFF4FFF3FFF2FFF1; - - if (simdSize == 16) - { - vecCon2->gtSimdVal.u64[1] = 0x8000800080008000; - vecCon3->gtSimdVal.u64[1] = 0xFFF8FFF7FFF6FFF5; - } - break; - } - - case TYP_INT: - case TYP_UINT: - case TYP_FLOAT: - { - simdBaseType = TYP_INT; - simdBaseJitType = CORINFO_TYPE_INT; - - vecCon2->gtSimdVal.u64[0] = 0x8000000080000000; - vecCon3->gtSimdVal.u64[0] = 0xFFFFFFE2FFFFFFE1; - - if (simdSize == 16) - { - vecCon2->gtSimdVal.u64[1] = 0x8000000080000000; - vecCon3->gtSimdVal.u64[1] = 0xFFFFFFE4FFFFFFE3; - } - break; - } - - case TYP_LONG: - case TYP_ULONG: - case TYP_DOUBLE: - { - simdBaseType = TYP_LONG; - simdBaseJitType = CORINFO_TYPE_LONG; - - vecCon2->gtSimdVal.u64[0] = 0x8000000000000000; - vecCon3->gtSimdVal.u64[0] = 0xFFFFFFFFFFFFFFC1; - - if (simdSize == 16) - { - vecCon2->gtSimdVal.u64[1] = 0x8000000000000000; - vecCon3->gtSimdVal.u64[1] = 0xFFFFFFFFFFFFFFC2; - } - break; - } - - default: - { - unreached(); - } - } - - op3 = vecCon3; - op2 = vecCon2; - op1 = gtNewSimdHWIntrinsicNode(simdType, op1, op2, NI_AdvSimd_And, simdBaseJitType, simdSize); - - NamedIntrinsic shiftIntrinsic = NI_AdvSimd_ShiftLogical; - - if ((simdSize == 8) && varTypeIsLong(simdBaseType)) - { - shiftIntrinsic = NI_AdvSimd_ShiftLogicalScalar; - } - - op1 = gtNewSimdHWIntrinsicNode(simdType, op1, op3, shiftIntrinsic, simdBaseJitType, simdSize); - - if (varTypeIsByte(simdBaseType) && (simdSize == 16)) - { - op1 = impCloneExpr(op1, &op2, CHECK_SPILL_ALL, - nullptr DEBUGARG("Clone op1 for vector extractmostsignificantbits")); - - op1 = gtNewSimdGetLowerNode(TYP_SIMD8, op1, simdBaseJitType, simdSize); - op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, 8); - op1 = gtNewSimdToScalarNode(genActualType(simdBaseType), op1, simdBaseJitType, 8); - op1 = gtNewCastNode(TYP_INT, op1, /* isUnsigned */ true, TYP_INT); - - GenTree* zero = gtNewZeroConNode(TYP_SIMD16); - ssize_t index = 8 / genTypeSize(simdBaseType); - - op2 = gtNewSimdGetUpperNode(TYP_SIMD8, op2, simdBaseJitType, simdSize); - op2 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op2, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, 8); - op2 = gtNewSimdToScalarNode(genActualType(simdBaseType), op2, simdBaseJitType, 8); - op2 = gtNewCastNode(TYP_INT, op2, /* isUnsigned */ true, TYP_INT); - - op2 = gtNewOperNode(GT_LSH, TYP_INT, op2, gtNewIconNode(8)); - retNode = gtNewOperNode(GT_OR, TYP_INT, op1, op2); - } - else - { - if (!varTypeIsLong(simdBaseType)) - { - if ((simdSize == 8) && ((simdBaseType == TYP_INT) || (simdBaseType == TYP_UINT))) - { - op1 = impCloneExpr(op1, &op2, CHECK_SPILL_ALL, - nullptr DEBUGARG("Clone op1 for vector extractmostsignificantbits")); - op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, op2, NI_AdvSimd_AddPairwise, simdBaseJitType, - simdSize); - } - else - { - op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, - simdSize); - } - } - else if (simdSize == 16) - { - op1 = gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddPairwiseScalar, simdBaseJitType, - simdSize); - } - - retNode = gtNewSimdToScalarNode(genActualType(simdBaseType), op1, simdBaseJitType, 8); - - if ((simdBaseType != TYP_INT) && (simdBaseType != TYP_UINT)) - { - retNode = gtNewCastNode(TYP_INT, retNode, /* isUnsigned */ true, TYP_INT); - } - } + op1 = impSIMDPopStack(); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, simdBaseJitType, simdSize); break; } diff --git a/src/runtime/src/coreclr/jit/hwintrinsiclistarm64.h b/src/runtime/src/coreclr/jit/hwintrinsiclistarm64.h index 25433249351..ec721f567c5 100644 --- a/src/runtime/src/coreclr/jit/hwintrinsiclistarm64.h +++ b/src/runtime/src/coreclr/jit/hwintrinsiclistarm64.h @@ -51,7 +51,7 @@ HARDWARE_INTRINSIC(Vector64, CreateSequence, HARDWARE_INTRINSIC(Vector64, Dot, 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_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector64, Equals, 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_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, EqualsAny, 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_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector64, ExtractMostSignificantBits, 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_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector64, ExtractMostSignificantBits, 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_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, Floor, 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_InvalidNodeId) HARDWARE_INTRINSIC(Vector64, FusedMultiplyAdd, 8, 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_InvalidNodeId) 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_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SupportsContainment) @@ -182,7 +182,7 @@ HARDWARE_INTRINSIC(Vector128, CreateSequence, HARDWARE_INTRINSIC(Vector128, Dot, 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_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, Equals, 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_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, EqualsAny, 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_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 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_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 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_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, Floor, 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_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, FusedMultiplyAdd, 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_InvalidNodeId) 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_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SupportsContainment) diff --git a/src/runtime/src/coreclr/jit/hwintrinsiclistarm64sve.h b/src/runtime/src/coreclr/jit/hwintrinsiclistarm64sve.h index e122c847bb5..e29129dde94 100644 --- a/src/runtime/src/coreclr/jit/hwintrinsiclistarm64sve.h +++ b/src/runtime/src/coreclr/jit/hwintrinsiclistarm64sve.h @@ -324,6 +324,8 @@ HARDWARE_INTRINSIC(Sve2, AddHighNarrowingEven, HARDWARE_INTRINSIC(Sve2, AddHighNarrowingOdd, -1, 3, {INS_sve_addhnt, INS_sve_addhnt, INS_sve_addhnt, INS_sve_addhnt, INS_sve_addhnt, INS_sve_addhnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, AddPairwise, -1, -1, {INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_addp, INS_sve_faddp, INS_sve_faddp}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation|HW_Flag_ReduceOperation) HARDWARE_INTRINSIC(Sve2, AddPairwiseWideningAndAdd, -1, -1, {INS_invalid, INS_invalid, INS_sve_sadalp, INS_sve_uadalp, INS_sve_sadalp, INS_sve_uadalp, INS_sve_sadalp, INS_sve_uadalp, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve2, AddRoundedHighNarrowingEven, -1, 2, {INS_sve_raddhnb, INS_sve_raddhnb, INS_sve_raddhnb, INS_sve_raddhnb, INS_sve_raddhnb, INS_sve_raddhnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, AddRoundedHighNarrowingOdd, -1, 3, {INS_sve_raddhnt, INS_sve_raddhnt, INS_sve_raddhnt, INS_sve_raddhnt, INS_sve_raddhnt, INS_sve_raddhnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, AddSaturate, -1, -1, {INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_sve_sqadd, INS_sve_uqadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_OptionalEmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, AddSaturateWithSignedAddend, -1, -1, {INS_invalid, INS_sve_usqadd, INS_invalid, INS_sve_usqadd, INS_invalid, INS_sve_usqadd, INS_invalid, INS_sve_usqadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, AddSaturateWithUnsignedAddend, -1, -1, {INS_sve_suqadd, INS_invalid, INS_sve_suqadd, INS_invalid, INS_sve_suqadd, INS_invalid, INS_sve_suqadd, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) @@ -335,9 +337,28 @@ HARDWARE_INTRINSIC(Sve2, BitwiseSelect, HARDWARE_INTRINSIC(Sve2, BitwiseSelectLeftInverted, -1, 3, {INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_sve_bsl1n, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, BitwiseSelectRightInverted, -1, 3, {INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_sve_bsl2n, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, FusedAddHalving, -1, -1, {INS_sve_shadd, INS_sve_uhadd, INS_sve_shadd, INS_sve_uhadd, INS_sve_shadd, INS_sve_uhadd, INS_sve_shadd, INS_sve_uhadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) +HARDWARE_INTRINSIC(Sve2, FusedAddRoundedHalving, -1, -1, {INS_sve_srhadd, INS_sve_urhadd, INS_sve_srhadd, INS_sve_urhadd, INS_sve_srhadd, INS_sve_urhadd, INS_sve_srhadd, INS_sve_urhadd, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, FusedSubtractHalving, -1, -1, {INS_sve_shsub, INS_sve_uhsub, INS_sve_shsub, INS_sve_uhsub, INS_sve_shsub, INS_sve_uhsub, INS_sve_shsub, INS_sve_uhsub, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, InterleavingXorEvenOdd, -1, 3, {INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_sve_eorbt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, InterleavingXorOddEven, -1, 3, {INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_sve_eortb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyAddBySelectedScalar, -1, 4, {INS_invalid, INS_invalid, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_sve_mla, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalar, -1, 3, {INS_invalid, INS_invalid, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_sve_mul, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningEven, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_smullb, INS_sve_umullb, INS_sve_smullb, INS_sve_umullb, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningEvenAndAdd, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_smlalb, INS_sve_umlalb, INS_sve_smlalb, INS_sve_umlalb, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningEvenAndSubtract, -1, 4, {INS_invalid, INS_invalid, INS_sve_smlslb, INS_sve_umlslb, INS_sve_smlslb, INS_sve_umlslb, INS_sve_smlslb, INS_sve_umlslb, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningOdd, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_smullt, INS_sve_umullt, INS_sve_smullt, INS_sve_umullt, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningOddAndAdd, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_smlalt, INS_sve_umlalt, INS_sve_smlalt, INS_sve_umlalt, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyBySelectedScalarWideningOddAndSubtract, -1, 4, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_smlslt, INS_sve_umlslt, INS_sve_smlslt, INS_sve_umlslt, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasRMWSemantics|HW_Flag_HasImmediateOperand|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplySubtractBySelectedScalar, -1, 4, {INS_invalid, INS_invalid, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_sve_mls, INS_invalid, INS_invalid}, HW_Category_SIMDByIndexedElement, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics|HW_Flag_LowVectorOperation) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningEven, -1, 2, {INS_invalid, INS_invalid, INS_sve_smullb, INS_sve_umullb, INS_sve_smullb, INS_sve_umullb, INS_sve_smullb, INS_sve_umullb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningEvenAndAdd, -1, 3, {INS_invalid, INS_invalid, INS_sve_smlalb, INS_sve_umlalb, INS_sve_smlalb, INS_sve_umlalb, INS_sve_smlalb, INS_sve_umlalb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningEvenAndSubtract, -1, 3, {INS_invalid, INS_invalid, INS_sve_smlslb, INS_sve_umlslb, INS_sve_smlslb, INS_sve_umlslb, INS_sve_smlslb, INS_sve_umlslb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningOdd, -1, 2, {INS_invalid, INS_invalid, INS_sve_smullt, INS_sve_umullt, INS_sve_smullt, INS_sve_umullt, INS_sve_smullt, INS_sve_umullt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningOddAndAdd, -1, 3, {INS_invalid, INS_invalid, INS_sve_smlalt, INS_sve_umlalt, INS_sve_smlalt, INS_sve_umlalt, INS_sve_smlalt, INS_sve_umlalt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, MultiplyWideningOddAndSubtract, -1, 3, {INS_invalid, INS_invalid, INS_sve_smlslt, INS_sve_umlslt, INS_sve_smlslt, INS_sve_umlslt, INS_sve_smlslt, INS_sve_umlslt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, PolynomialMultiply, -1, 2, {INS_sve_pmul, INS_sve_pmul, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, PolynomialMultiplyWideningEven, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_sve_pmullb, INS_invalid, INS_invalid, INS_invalid, INS_sve_pmullb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, PolynomialMultiplyWideningOdd, -1, 2, {INS_invalid, INS_invalid, INS_invalid, INS_sve_pmullt, INS_invalid, INS_invalid, INS_invalid, INS_sve_pmullt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, ShiftArithmeticRounded, -1, -1, {INS_sve_srshl, INS_invalid, INS_sve_srshl, INS_invalid, INS_sve_srshl, INS_invalid, INS_sve_srshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, ShiftArithmeticRoundedSaturate, -1, -1, {INS_sve_sqrshl, INS_invalid, INS_sve_sqrshl, INS_invalid, INS_sve_sqrshl, INS_invalid, INS_sve_sqrshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) HARDWARE_INTRINSIC(Sve2, ShiftArithmeticSaturate, -1, -1, {INS_sve_sqshl, INS_invalid, INS_sve_sqshl, INS_invalid, INS_sve_sqshl, INS_invalid, INS_sve_sqshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics|HW_Flag_LowMaskedOperation) @@ -369,16 +390,17 @@ HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingEven, HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingOdd, -1, 3, {INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_sve_rshrnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingSaturateEven, -1, 2, {INS_invalid, INS_sve_uqrshrnb, INS_invalid, INS_sve_uqrshrnb, INS_invalid, INS_sve_uqrshrnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand) HARDWARE_INTRINSIC(Sve2, ShiftRightLogicalRoundedNarrowingSaturateOdd, -1, 3, {INS_invalid, INS_sve_uqrshrnt, INS_invalid, INS_sve_uqrshrnt, INS_invalid, INS_sve_uqrshrnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_Scalable|HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, SubtractBorrowWideningEven, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sbclb, INS_invalid, INS_sve_sbclb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, SubtractBorrowWideningOdd, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sbclt, INS_invalid, INS_sve_sbclt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, SubtractHighNarrowingEven, -1, 2, {INS_sve_subhnb, INS_sve_subhnb, INS_sve_subhnb, INS_sve_subhnb, INS_sve_subhnb, INS_sve_subhnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, SubtractHighNarrowingOdd, -1, 3, {INS_sve_subhnt, INS_sve_subhnt, INS_sve_subhnt, INS_sve_subhnt, INS_sve_subhnt, INS_sve_subhnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) +HARDWARE_INTRINSIC(Sve2, SubtractRoundedHighNarrowingEven, -1, 2, {INS_sve_rsubhnb, INS_sve_rsubhnb, INS_sve_rsubhnb, INS_sve_rsubhnb, INS_sve_rsubhnb, INS_sve_rsubhnb, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) +HARDWARE_INTRINSIC(Sve2, SubtractRoundedHighNarrowingOdd, -1, 3, {INS_sve_rsubhnt, INS_sve_rsubhnt, INS_sve_rsubhnt, INS_sve_rsubhnt, INS_sve_rsubhnt, INS_sve_rsubhnt, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, SubtractSaturate, -1, -1, {INS_sve_sqsub, INS_sve_uqsub, INS_sve_sqsub, INS_sve_uqsub, INS_sve_sqsub, INS_sve_uqsub, INS_sve_sqsub, INS_sve_uqsub, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sve2, SubtractSaturateReversed, -1, -1, {INS_sve_sqsubr, INS_sve_uqsubr, INS_sve_sqsubr, INS_sve_uqsubr, INS_sve_sqsubr, INS_sve_uqsubr, INS_sve_sqsubr, INS_sve_uqsubr, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_EmbeddedMaskedOperation|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, SubtractWideningEven, -1, 2, {INS_invalid, INS_invalid, INS_sve_ssubwb, INS_sve_usubwb, INS_sve_ssubwb, INS_sve_usubwb, INS_sve_ssubwb, INS_sve_usubwb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve2, SubtractWideningEvenOdd, -1, 2, {INS_invalid, INS_invalid, INS_sve_ssublbt, INS_invalid, INS_sve_ssublbt, INS_invalid, INS_sve_ssublbt, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) HARDWARE_INTRINSIC(Sve2, SubtractWideningOdd, -1, 2, {INS_invalid, INS_invalid, INS_sve_ssubwt, INS_sve_usubwt, INS_sve_ssubwt, INS_sve_usubwt, INS_sve_ssubwt, INS_sve_usubwt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve2, SubtractWideningOddEven, -1, 2, {INS_invalid, INS_invalid, INS_sve_ssubltb, INS_invalid, INS_sve_ssubltb, INS_invalid, INS_sve_ssubltb, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable) -HARDWARE_INTRINSIC(Sve2, SubtractWithBorrowWideningLower, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sbclb, INS_invalid, INS_sve_sbclb, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) -HARDWARE_INTRINSIC(Sve2, SubtractWithBorrowWideningUpper, -1, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sve_sbclt, INS_invalid, INS_sve_sbclt, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, VectorTableLookup, -1, 2, {INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl, INS_sve_tbl}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_NeedsConsecutiveRegisters|HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Sve2, VectorTableLookupExtension, -1, 3, {INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx, INS_sve_tbx}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_HasRMWSemantics) HARDWARE_INTRINSIC(Sve2, Xor, -1, 3, {INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_sve_eor3, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_Scalable|HW_Flag_SpecialCodeGen|HW_Flag_HasRMWSemantics) diff --git a/src/runtime/src/coreclr/jit/hwintrinsiclistxarch.h b/src/runtime/src/coreclr/jit/hwintrinsiclistxarch.h index 7786d481a11..be680becff0 100644 --- a/src/runtime/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/runtime/src/coreclr/jit/hwintrinsiclistxarch.h @@ -69,7 +69,7 @@ HARDWARE_INTRINSIC(Vector128, CreateSequence, HARDWARE_INTRINSIC(Vector128, Dot, 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_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector128, Equals, 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_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, EqualsAny, 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_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 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_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 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_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, Floor, 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_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, FusedMultiplyAdd, 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_InvalidNodeId) HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_extractps, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) @@ -197,7 +197,7 @@ HARDWARE_INTRINSIC(Vector256, CreateSequence, HARDWARE_INTRINSIC(Vector256, Dot, 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_NoCodeGen|HW_Flag_BaseTypeFromFirstArg) HARDWARE_INTRINSIC(Vector256, Equals, 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_InvalidNodeId) HARDWARE_INTRINSIC(Vector256, EqualsAny, 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_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) -HARDWARE_INTRINSIC(Vector256, ExtractMostSignificantBits, 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_InvalidNodeId|HW_Flag_BaseTypeFromFirstArg) +HARDWARE_INTRINSIC(Vector256, ExtractMostSignificantBits, 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_BaseTypeFromFirstArg|HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector256, Floor, 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_InvalidNodeId|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, FusedMultiplyAdd, 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_InvalidNodeId) 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_BaseTypeFromFirstArg|HW_Flag_AvxOnlyCompatible) diff --git a/src/runtime/src/coreclr/jit/hwintrinsicxarch.cpp b/src/runtime/src/coreclr/jit/hwintrinsicxarch.cpp index a333b87bbff..c614918b207 100644 --- a/src/runtime/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/runtime/src/coreclr/jit/hwintrinsicxarch.cpp @@ -2406,7 +2406,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { op1 = impSIMDPopStack(); - op1 = gtNewSimdCvtVectorToMaskNode(TYP_MASK, op1, simdBaseJitType, simdSize); + op1 = gtFoldExpr(gtNewSimdCvtVectorToMaskNode(TYP_MASK, op1, simdBaseJitType, simdSize)); retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, simdBaseJitType, simdSize); break; } @@ -2432,64 +2432,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case TYP_SHORT: case TYP_USHORT: { - simd_t simdVal = {}; - - assert((simdSize == 16) || (simdSize == 32) || (simdSize == 64)); - simdBaseJitType = varTypeIsUnsigned(simdBaseType) ? CORINFO_TYPE_UBYTE : CORINFO_TYPE_BYTE; - - // We want to tightly pack the most significant byte of each short/ushort - // and then zero the tightly packed least significant bytes - // - // The most significant bit being set means zero the value - - simdVal.u64[0] = 0x0F0D0B0907050301; - simdVal.u64[1] = 0x8080808080808080; - - if (simdSize == 32) - { - // Vector256 works on 2x128-bit lanes, so repeat the same indices for the upper lane - - simdVal.u64[2] = 0x0F0D0B0907050301; - simdVal.u64[3] = 0x8080808080808080; - - shuffleIntrinsic = NI_AVX2_Shuffle; - moveMaskIntrinsic = NI_X86Base_MoveMask; - } - else if (compOpportunisticallyDependsOn(InstructionSet_SSE42)) - { - shuffleIntrinsic = NI_SSE42_Shuffle; - moveMaskIntrinsic = NI_X86Base_MoveMask; - } - else - { - return nullptr; - } - - op2 = gtNewVconNode(simdType); - memcpy(&op2->AsVecCon()->gtSimdVal, &simdVal, simdSize); - - op1 = impSIMDPopStack(); - op1 = gtNewSimdHWIntrinsicNode(simdType, op1, op2, shuffleIntrinsic, simdBaseJitType, simdSize); - - if (simdSize == 32) - { - CorInfoType simdOtherJitType; - - // Since Vector256 is 2x128-bit lanes we need a full width permutation so we get the lower - // 64-bits of each lane next to eachother. The upper bits should be zero, but also don't - // matter so we can also then simplify down to a 128-bit move mask. - - simdOtherJitType = (simdBaseType == TYP_UBYTE) ? CORINFO_TYPE_ULONG : CORINFO_TYPE_LONG; - - op1 = gtNewSimdHWIntrinsicNode(simdType, op1, gtNewIconNode(0xD8), NI_AVX2_Permute4x64, - simdOtherJitType, simdSize); - - simdType = TYP_SIMD16; - - op1 = gtNewSimdGetLowerNode(simdType, op1, simdBaseJitType, simdSize); - - simdSize = 16; - } + op1 = impSIMDPopStack(); + moveMaskIntrinsic = intrinsic; break; } @@ -2523,6 +2467,14 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, assert(op1 != nullptr); retNode = gtNewSimdHWIntrinsicNode(retType, op1, moveMaskIntrinsic, simdBaseJitType, simdSize); + + if ((simdSize == 16) && varTypeIsShort(simdBaseType)) + { + if (!compOpportunisticallyDependsOn(InstructionSet_SSE42)) + { + retNode->AsHWIntrinsic()->SetMethodHandle(this, method R2RARG(*entryPoint)); + } + } } break; } @@ -4993,7 +4945,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, } } intrinsic = NI_AVX512_BlendVariableMask; - op3 = gtNewSimdCvtVectorToMaskNode(TYP_MASK, op3, simdBaseJitType, simdSize); + op3 = gtFoldExpr(gtNewSimdCvtVectorToMaskNode(TYP_MASK, op3, simdBaseJitType, simdSize)); } retNode = gtNewSimdHWIntrinsicNode(retType, op1, op2, op3, intrinsic, simdBaseJitType, simdSize); break; @@ -5531,7 +5483,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, { retType = getSIMDTypeForSize(simdSize); assert(retType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass))); - retNode = gtNewSimdCvtMaskToVectorNode(retType, retNode, simdBaseJitType, simdSize); + retNode = gtNewSimdCvtMaskToVectorNode(retType, gtFoldExpr(retNode), simdBaseJitType, simdSize); } else if (isMinMaxIntrinsic) { diff --git a/src/runtime/src/coreclr/jit/importer.cpp b/src/runtime/src/coreclr/jit/importer.cpp index bee5fe142f4..70b78bc0477 100644 --- a/src/runtime/src/coreclr/jit/importer.cpp +++ b/src/runtime/src/coreclr/jit/importer.cpp @@ -8056,8 +8056,8 @@ void Compiler::impImportBlockCode(BasicBlock* block) { // Find the jump target size_t switchVal = (size_t)op1->AsIntCon()->gtIconVal; - unsigned jumpCnt = block->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTab = block->GetSwitchTargets()->bbsDstTab; + unsigned jumpCnt = block->GetSwitchTargets()->GetCaseCount(); + FlowEdge** jumpTab = block->GetSwitchTargets()->GetCases(); bool foundVal = false; Metrics.ImporterSwitchFold++; @@ -8084,15 +8084,11 @@ void Compiler::impImportBlockCode(BasicBlock* block) } assert(foundVal); -#ifdef DEBUG - if (verbose) - { - printf("\nSwitch folded at " FMT_BB "\n", block->bbNum); - printf(FMT_BB " becomes a %s", block->bbNum, "BBJ_ALWAYS"); - printf(" to " FMT_BB, block->GetTarget()->bbNum); - printf("\n"); - } -#endif + JITDUMP("\nSwitch folded at " FMT_BB "\n", block->bbNum); + JITDUMP(FMT_BB " becomes a %s", block->bbNum, "BBJ_ALWAYS"); + JITDUMP(" to " FMT_BB, block->GetTarget()->bbNum); + JITDUMP("\n"); + if (block->hasProfileWeight()) { // We are unlikely to be able to repair the profile. @@ -11841,7 +11837,7 @@ void Compiler::impImportBlock(BasicBlock* block) addStmt = impExtractLastStmt(); assert(addStmt->GetRootNode()->OperIs(GT_SWITCH)); - for (BasicBlock* const tgtBlock : block->SwitchTargets()) + for (BasicBlock* const tgtBlock : block->SwitchSuccs()) { multRef |= tgtBlock->bbRefs; @@ -12758,19 +12754,13 @@ void Compiler::impFixPredLists() } } - BBehfDesc* jumpEhf = new (this, CMK_BasicBlock) BBehfDesc; + BBJumpTable* jumpEhf; - // It's possible for the `finally` to have no CALLFINALLY predecessors if the `try` block - // has an unconditional `throw` (the finally will still be invoked in the exceptional - // case via the runtime). In that case, jumpEhf->bbeCount remains the default, zero, - // and jumpEhf->bbeSuccs remains the default, nullptr. if (predCount > 0) { - jumpEhf->bbeCount = predCount; - jumpEhf->bbeSuccs = new (this, CMK_FlowEdge) FlowEdge*[predCount]; - - unsigned predNum = 0; - weight_t remainingLikelihood = 1.0; + FlowEdge** const succTab = new (this, CMK_FlowEdge) FlowEdge*[predCount]; + unsigned predNum = 0; + weight_t remainingLikelihood = 1.0; for (BasicBlock* const predBlock : finallyBegBlock->PredBlocks()) { // We only care about preds that are callfinallies. @@ -12799,8 +12789,7 @@ void Compiler::impFixPredLists() newEdge->setLikelihood(1.0 / predCount); } - jumpEhf->bbeSuccs[predNum] = newEdge; - ++predNum; + succTab[predNum++] = newEdge; if (!added) { @@ -12808,7 +12797,17 @@ void Compiler::impFixPredLists() added = true; } } + assert(predNum == predCount); + jumpEhf = new (this, CMK_FlowEdge) BBJumpTable(succTab, predCount); + } + else + { + // It's possible for the `finally` to have no CALLFINALLY predecessors if the `try` block + // has an unconditional `throw` (the finally will still be invoked in the exceptional + // case via the runtime). In that case, jumpEhf->succCount remains the default, zero, + // and jumpEhf->succs remains the default, nullptr. + jumpEhf = new (this, CMK_FlowEdge) BBJumpTable(); } finallyBlock->SetEhfTargets(jumpEhf); diff --git a/src/runtime/src/coreclr/jit/lower.cpp b/src/runtime/src/coreclr/jit/lower.cpp index 838a4a243e7..dbe684b3b39 100644 --- a/src/runtime/src/coreclr/jit/lower.cpp +++ b/src/runtime/src/coreclr/jit/lower.cpp @@ -844,9 +844,11 @@ GenTree* Lowering::LowerSwitch(GenTree* node) // jumpCnt is the number of elements in the jump table array. // jumpTab is the actual pointer to the jump table array. // targetCnt is the number of unique targets in the jump table array. - const unsigned jumpCnt = originalSwitchBB->GetSwitchTargets()->bbsCount; - FlowEdge** const jumpTab = originalSwitchBB->GetSwitchTargets()->bbsDstTab; - const unsigned targetCnt = originalSwitchBB->NumSucc(comp); + // uniqueSuccs is the array of the switch's unique successors. + const unsigned jumpCnt = originalSwitchBB->GetSwitchTargets()->GetCaseCount(); + FlowEdge** const jumpTab = originalSwitchBB->GetSwitchTargets()->GetCases(); + unsigned targetCnt = originalSwitchBB->GetSwitchTargets()->GetSuccCount(); + FlowEdge** const uniqueSuccs = originalSwitchBB->GetSwitchTargets()->GetSuccs(); // GT_SWITCH must be a top-level node with no use. #ifdef DEBUG @@ -868,10 +870,9 @@ GenTree* Lowering::LowerSwitch(GenTree* node) originalSwitchBB->SetKindAndTargetEdge(BBJ_ALWAYS, jumpTab[0]); // Remove extra predecessor links if there was more than one case. - for (unsigned i = 1; i < jumpCnt; ++i) - { - comp->fgRemoveRefPred(jumpTab[i]); - } + const unsigned dupCount = originalSwitchBB->GetTargetEdge()->getDupCount(); + originalSwitchBB->GetTargetEdge()->decrementDupCount(dupCount - 1); + originalSwitchBB->GetTarget()->bbRefs -= (dupCount - 1); // We have to get rid of the GT_SWITCH node but a child might have side effects so just assign // the result of the child subtree to a temp. @@ -953,7 +954,7 @@ GenTree* Lowering::LowerSwitch(GenTree* node) assert(originalSwitchBB->TargetIs(afterDefaultCondBlock)); assert(originalSwitchBB->JumpsToNext()); assert(afterDefaultCondBlock->KindIs(BBJ_SWITCH)); - assert(afterDefaultCondBlock->GetSwitchTargets()->bbsHasDefault); + assert(afterDefaultCondBlock->GetSwitchTargets()->HasDefaultCase()); assert(afterDefaultCondBlock->isEmpty()); // Nothing here yet. // The GT_SWITCH code is still in originalSwitchBB (it will be removed later). @@ -997,36 +998,16 @@ GenTree* Lowering::LowerSwitch(GenTree* node) // If we originally had 2 unique successors, check to see whether there is a unique // non-default case, in which case we can eliminate the switch altogether. // Note that the single unique successor case is handled above. - FlowEdge* uniqueSucc = nullptr; - if (targetCnt == 2) - { - uniqueSucc = jumpTab[0]; - noway_assert(jumpCnt >= 2); - for (unsigned i = 1; i < jumpCnt - 1; i++) - { - if (jumpTab[i] != uniqueSucc) - { - uniqueSucc = nullptr; - break; - } - } - } - if (uniqueSucc != nullptr) + if ((targetCnt == 2) && (defaultEdge->getDupCount() == 0)) { - // If the unique successor immediately follows this block, we have nothing to do - - // it will simply fall-through after we remove the switch, below. - // Otherwise, make this a BBJ_ALWAYS. - // Now, fixup the predecessor links to uniqueSucc's target block. In the original jumpTab: - // jumpTab[i-1] was the default target, which we handled above, - // jumpTab[0] is the first target, and we'll leave that predecessor link. - // Remove any additional predecessor links to uniqueSucc's target block. - for (unsigned i = 1; i < jumpCnt - 1; ++i) - { - assert(jumpTab[i] == uniqueSucc); - comp->fgRemoveRefPred(uniqueSucc); - } - + // The default case was peeled off, and we have only one other unique successor. + // Jump directly to this remaining successor. + FlowEdge* const uniqueSucc = (uniqueSuccs[0] == defaultEdge) ? uniqueSuccs[1] : uniqueSuccs[0]; + assert(uniqueSucc != defaultEdge); afterDefaultCondBlock->SetKindAndTargetEdge(BBJ_ALWAYS, uniqueSucc); + const unsigned dupCount = uniqueSucc->getDupCount(); + uniqueSucc->decrementDupCount(dupCount - 1); + uniqueSucc->getDestinationBlock()->bbRefs -= (dupCount - 1); } // If the number of possible destinations is small enough, we proceed to expand the switch // into a series of conditional branches, otherwise we follow the jump table based switch @@ -1209,9 +1190,9 @@ GenTree* Lowering::LowerSwitch(GenTree* node) if (afterDefaultCondBlock->hasProfileWeight()) { bool profileInconsistent = false; - for (unsigned i = 0; i < jumpCnt - 1; i++) + for (unsigned i = 0; i < targetCnt; i++) { - BasicBlock* const targetBlock = jumpTab[i]->getDestinationBlock(); + BasicBlock* const targetBlock = uniqueSuccs[i]->getDestinationBlock(); targetBlock->setBBProfileWeight(targetBlock->computeIncomingWeight()); profileInconsistent |= (targetBlock->NumSucc() > 0); } @@ -1255,24 +1236,29 @@ GenTree* Lowering::LowerSwitch(GenTree* node) switchBlockRange.InsertAfter(switchValue, switchTable, switchJump); // This block no longer has a default switch case. - // If no other cases branch to this successor, remove it from the switch map entry. + // If no other cases branch to this successor, remove it from the unique successor table. if (defaultEdge->getDupCount() == 0) { - comp->fgRemoveSuccFromSwitchDescMapEntry(afterDefaultCondBlock, defaultEdge); + for (unsigned i = 0; i < targetCnt; i++) + { + FlowEdge* const edge = uniqueSuccs[i]; + if (edge == defaultEdge) + { + afterDefaultCondBlock->GetSwitchTargets()->RemoveSucc(i); + break; + } + } + + assert(targetCnt == (afterDefaultCondBlock->GetSwitchTargets()->GetSuccCount() + 1)); + targetCnt--; } - afterDefaultCondBlock->GetSwitchTargets()->removeDefault(); + afterDefaultCondBlock->GetSwitchTargets()->RemoveDefaultCase(); // We need to scale up the likelihood of the remaining switch edges, now that we've peeled off // the default case. But if the remaining likelihood is zero (default likelihood was 1.0), // we don't know the case likelihoods. Instead, divide likelihood evenly among all cases. // - // First, rebuild the unique succ set - // - Compiler::SwitchUniqueSuccSet successors = comp->GetDescriptorForSwitch(afterDefaultCondBlock); - - // Then fix each successor edge - // if (Compiler::fgProfileWeightsEqual(defaultLikelihood, 1.0, 0.001)) { JITDUMP("Zero weight switch block " FMT_BB ", distributing likelihoods equally per case\n", @@ -1280,9 +1266,9 @@ GenTree* Lowering::LowerSwitch(GenTree* node) // jumpCnt-1 here because we peeled the default after copying this value. weight_t const newLikelihood = 1.0 / (jumpCnt - 1); bool profileInconsistent = false; - for (unsigned i = 0; i < successors.numDistinctSuccs; i++) + for (unsigned i = 0; i < targetCnt; i++) { - FlowEdge* const edge = successors.nonDuplicates[i]; + FlowEdge* const edge = uniqueSuccs[i]; weight_t const oldEdgeWeight = edge->getLikelyWeight(); edge->setLikelihood(newLikelihood * edge->getDupCount()); weight_t const newEdgeWeight = edge->getLikelyWeight(); @@ -1307,9 +1293,9 @@ GenTree* Lowering::LowerSwitch(GenTree* node) weight_t const scaleFactor = 1.0 / (1.0 - defaultLikelihood); JITDUMP("Scaling switch block " FMT_BB " likelihoods by " FMT_WT "\n", afterDefaultCondBlock->bbNum, scaleFactor); - for (unsigned i = 0; i < successors.numDistinctSuccs; i++) + for (unsigned i = 0; i < targetCnt; i++) { - FlowEdge* const edge = successors.nonDuplicates[i]; + FlowEdge* const edge = uniqueSuccs[i]; weight_t newLikelihood = scaleFactor * edge->getLikelihood(); if (newLikelihood > 1.0) @@ -1322,11 +1308,6 @@ GenTree* Lowering::LowerSwitch(GenTree* node) } } } - else - { - // 'afterDefaultCondBlock' is no longer a switch block. Remove its switch map entry. - comp->fgInvalidateSwitchDescMapEntry(afterDefaultCondBlock); - } } GenTree* next = node->gtNext; diff --git a/src/runtime/src/coreclr/jit/lsraarm64.cpp b/src/runtime/src/coreclr/jit/lsraarm64.cpp index 15f658c656e..87d73acd0da 100644 --- a/src/runtime/src/coreclr/jit/lsraarm64.cpp +++ b/src/runtime/src/coreclr/jit/lsraarm64.cpp @@ -2164,9 +2164,18 @@ SingleTypeRegSet LinearScan::getOperandCandidates(GenTreeHWIntrinsic* intrinsicT case NI_Sve_FusedMultiplyAddBySelectedScalar: case NI_Sve_FusedMultiplySubtractBySelectedScalar: case NI_Sve_MultiplyAddRotateComplexBySelectedScalar: + case NI_Sve2_MultiplyAddBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalarWideningEvenAndAdd: + case NI_Sve2_MultiplyBySelectedScalarWideningOddAndAdd: + case NI_Sve2_MultiplySubtractBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract: + case NI_Sve2_MultiplyBySelectedScalarWideningOddAndSubtract: isLowVectorOpNum = (opNum == 3); break; case NI_Sve_MultiplyBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalar: + case NI_Sve2_MultiplyBySelectedScalarWideningEven: + case NI_Sve2_MultiplyBySelectedScalarWideningOdd: isLowVectorOpNum = (opNum == 2); break; default: @@ -2183,7 +2192,7 @@ SingleTypeRegSet LinearScan::getOperandCandidates(GenTreeHWIntrinsic* intrinsicT } else { - assert(baseElementSize == 4); + assert(baseElementSize <= 4); opCandidates = RBM_SVE_INDEXED_S_ELEMENT_ALLOWED_REGS.GetFloatRegSet(); } } diff --git a/src/runtime/src/coreclr/jit/morph.cpp b/src/runtime/src/coreclr/jit/morph.cpp index e00d9c3c408..e95b098e4ce 100644 --- a/src/runtime/src/coreclr/jit/morph.cpp +++ b/src/runtime/src/coreclr/jit/morph.cpp @@ -12888,8 +12888,8 @@ Compiler::FoldResult Compiler::fgFoldConditional(BasicBlock* block) // Find the actual jump target size_t switchVal = (size_t)cond->AsIntCon()->gtIconVal; - unsigned jumpCnt = block->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTab = block->GetSwitchTargets()->bbsDstTab; + unsigned jumpCnt = block->GetSwitchTargets()->GetCaseCount(); + FlowEdge** jumpTab = block->GetSwitchTargets()->GetCases(); bool foundVal = false; bool profileInconsistent = false; diff --git a/src/runtime/src/coreclr/jit/optimizer.cpp b/src/runtime/src/coreclr/jit/optimizer.cpp index 6399e26d3fc..3cdea868da5 100644 --- a/src/runtime/src/coreclr/jit/optimizer.cpp +++ b/src/runtime/src/coreclr/jit/optimizer.cpp @@ -585,14 +585,12 @@ void Compiler::optSetMappedBlockTargets(BasicBlock* blk, BasicBlock* newBlk, Blo case BBJ_EHFINALLYRET: { - BBehfDesc* currEhfDesc = blk->GetEhfTargets(); - BBehfDesc* newEhfDesc = new (this, CMK_BasicBlock) BBehfDesc; - newEhfDesc->bbeCount = currEhfDesc->bbeCount; - newEhfDesc->bbeSuccs = new (this, CMK_FlowEdge) FlowEdge*[newEhfDesc->bbeCount]; + BBJumpTable* currEhfDesc = blk->GetEhfTargets(); + FlowEdge** newSuccs = new (this, CMK_FlowEdge) FlowEdge*[currEhfDesc->GetSuccCount()]; - for (unsigned i = 0; i < newEhfDesc->bbeCount; i++) + for (unsigned i = 0; i < currEhfDesc->GetSuccCount(); i++) { - FlowEdge* const inspiringEdge = currEhfDesc->bbeSuccs[i]; + FlowEdge* const inspiringEdge = currEhfDesc->GetSucc(i); BasicBlock* const ehfTarget = inspiringEdge->getDestinationBlock(); FlowEdge* newEdge; @@ -606,9 +604,10 @@ void Compiler::optSetMappedBlockTargets(BasicBlock* blk, BasicBlock* newBlk, Blo newEdge = fgAddRefPred(ehfTarget, newBlk, inspiringEdge); } - newEhfDesc->bbeSuccs[i] = newEdge; + newSuccs[i] = newEdge; } + BBJumpTable* newEhfDesc = new (this, CMK_BasicBlock) BBJumpTable(newSuccs, currEhfDesc->GetSuccCount()); newBlk->SetEhf(newEhfDesc); break; } @@ -616,12 +615,12 @@ void Compiler::optSetMappedBlockTargets(BasicBlock* blk, BasicBlock* newBlk, Blo case BBJ_SWITCH: { BBswtDesc* currSwtDesc = blk->GetSwitchTargets(); - BBswtDesc* newSwtDesc = new (this, CMK_BasicBlock) BBswtDesc(currSwtDesc); - newSwtDesc->bbsDstTab = new (this, CMK_FlowEdge) FlowEdge*[newSwtDesc->bbsCount]; + BBswtDesc* newSwtDesc = new (this, CMK_BasicBlock) BBswtDesc(this, currSwtDesc); + FlowEdge** succPtr = newSwtDesc->GetSuccs(); - for (unsigned i = 0; i < newSwtDesc->bbsCount; i++) + for (unsigned i = 0; i < newSwtDesc->GetCaseCount(); i++) { - FlowEdge* const inspiringEdge = currSwtDesc->bbsDstTab[i]; + FlowEdge* const inspiringEdge = currSwtDesc->GetCase(i); BasicBlock* const switchTarget = inspiringEdge->getDestinationBlock(); FlowEdge* newEdge; @@ -637,13 +636,16 @@ void Compiler::optSetMappedBlockTargets(BasicBlock* blk, BasicBlock* newBlk, Blo // Transfer likelihood... instead of doing this gradually // for dup'd edges, we set it once, when we add the last dup. + // Also, add the new edge to the unique successor table. // if (newEdge->getDupCount() == inspiringEdge->getDupCount()) { newEdge->setLikelihood(inspiringEdge->getLikelihood()); + *succPtr = newEdge; + succPtr++; } - newSwtDesc->bbsDstTab[i] = newEdge; + newSwtDesc->GetCases()[i] = newEdge; } newBlk->SetSwitch(newSwtDesc); diff --git a/src/runtime/src/coreclr/jit/rationalize.cpp b/src/runtime/src/coreclr/jit/rationalize.cpp index 3f1b55136d0..fd1c2a774aa 100644 --- a/src/runtime/src/coreclr/jit/rationalize.cpp +++ b/src/runtime/src/coreclr/jit/rationalize.cpp @@ -418,6 +418,20 @@ void Rationalizer::RewriteHWIntrinsicAsUserCall(GenTree** use, ArrayStackcompOpportunisticallyDependsOn(InstructionSet_SSE42)) + { + // We want to keep this as is, because we'll rewrite it in post-order + return; + } + break; + } +#endif // TARGET_XARCH + default: { if (sigInfo.numArgs == 0) @@ -612,6 +626,17 @@ void Rationalizer::RewriteHWIntrinsic(GenTree** use, Compiler::GenTreeStack& par } #endif // TARGET_XARCH +#if defined(TARGET_ARM64) + case NI_Vector64_ExtractMostSignificantBits: +#elif defined(TARGET_XARCH) + case NI_Vector256_ExtractMostSignificantBits: +#endif + case NI_Vector128_ExtractMostSignificantBits: + { + RewriteHWIntrinsicExtractMsb(use, parents); + break; + } + default: { break; @@ -1305,6 +1330,316 @@ bool Rationalizer::ShouldRewriteToNonMaskHWIntrinsic(GenTree* node) return false; } #endif // TARGET_XARCH + +//---------------------------------------------------------------------------------------------- +// RewriteHWIntrinsicExtractMsb: Rewrites a hwintrinsic ExtractMostSignificantBytes operation +// +// Arguments: +// use - A pointer to the hwintrinsic node +// parents - A reference to tree walk data providing the context +// +void Rationalizer::RewriteHWIntrinsicExtractMsb(GenTree** use, Compiler::GenTreeStack& parents) +{ + GenTreeHWIntrinsic* node = (*use)->AsHWIntrinsic(); + + NamedIntrinsic intrinsic = node->GetHWIntrinsicId(); + CorInfoType simdBaseJitType = node->GetSimdBaseJitType(); + var_types simdBaseType = node->GetSimdBaseType(); + unsigned simdSize = node->GetSimdSize(); + var_types simdType = Compiler::getSIMDTypeForSize(simdSize); + + GenTree* op1 = node->Op(1); + +#if defined(TARGET_ARM64) + // ARM64 doesn't have a single instruction that performs the behavior so we'll emulate it instead. + // To do this, we effectively perform the following steps: + // 1. tmp = input & 0x80 ; and the input to clear all but the most significant bit + // 2. tmp = tmp >> index ; right shift each element by its index + // 3. tmp = sum(tmp) ; sum the elements together + + GenTreeVecCon* vecCon2 = comp->gtNewVconNode(simdType); + GenTreeVecCon* vecCon3 = comp->gtNewVconNode(simdType); + + switch (simdBaseType) + { + case TYP_BYTE: + case TYP_UBYTE: + { + simdBaseType = TYP_UBYTE; + simdBaseJitType = CORINFO_TYPE_UBYTE; + + vecCon2->gtSimdVal.u64[0] = 0x8080808080808080; + vecCon3->gtSimdVal.u64[0] = 0x00FFFEFDFCFBFAF9; + + if (simdSize == 16) + { + vecCon2->gtSimdVal.u64[1] = 0x8080808080808080; + vecCon3->gtSimdVal.u64[1] = 0x00FFFEFDFCFBFAF9; + } + break; + } + + case TYP_SHORT: + case TYP_USHORT: + { + simdBaseType = TYP_USHORT; + simdBaseJitType = CORINFO_TYPE_USHORT; + + vecCon2->gtSimdVal.u64[0] = 0x8000800080008000; + vecCon3->gtSimdVal.u64[0] = 0xFFF4FFF3FFF2FFF1; + + if (simdSize == 16) + { + vecCon2->gtSimdVal.u64[1] = 0x8000800080008000; + vecCon3->gtSimdVal.u64[1] = 0xFFF8FFF7FFF6FFF5; + } + break; + } + + case TYP_INT: + case TYP_UINT: + case TYP_FLOAT: + { + simdBaseType = TYP_INT; + simdBaseJitType = CORINFO_TYPE_INT; + + vecCon2->gtSimdVal.u64[0] = 0x8000000080000000; + vecCon3->gtSimdVal.u64[0] = 0xFFFFFFE2FFFFFFE1; + + if (simdSize == 16) + { + vecCon2->gtSimdVal.u64[1] = 0x8000000080000000; + vecCon3->gtSimdVal.u64[1] = 0xFFFFFFE4FFFFFFE3; + } + break; + } + + case TYP_LONG: + case TYP_ULONG: + case TYP_DOUBLE: + { + simdBaseType = TYP_LONG; + simdBaseJitType = CORINFO_TYPE_LONG; + + vecCon2->gtSimdVal.u64[0] = 0x8000000000000000; + vecCon3->gtSimdVal.u64[0] = 0xFFFFFFFFFFFFFFC1; + + if (simdSize == 16) + { + vecCon2->gtSimdVal.u64[1] = 0x8000000000000000; + vecCon3->gtSimdVal.u64[1] = 0xFFFFFFFFFFFFFFC2; + } + break; + } + + default: + { + unreached(); + } + } + + BlockRange().InsertAfter(op1, vecCon2); + GenTree* tmp = comp->gtNewSimdBinOpNode(GT_AND, simdType, op1, vecCon2, simdBaseJitType, simdSize); + BlockRange().InsertAfter(vecCon2, tmp); + op1 = tmp; + + if ((simdSize == 8) && varTypeIsLong(simdBaseType)) + { + intrinsic = NI_AdvSimd_ShiftLogicalScalar; + } + else + { + intrinsic = NI_AdvSimd_ShiftLogical; + } + + BlockRange().InsertAfter(op1, vecCon3); + tmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, vecCon3, intrinsic, simdBaseJitType, simdSize); + BlockRange().InsertAfter(vecCon3, tmp); + op1 = tmp; + + if (varTypeIsByte(simdBaseType) && (simdSize == 16)) + { + // For byte/sbyte, we also need to handle the fact that we can only shift by up to 8 + // but for Vector128, we have 16 elements to handle. In that scenario, we will widen + // to ushort and combine the lower/upper halves. + + LIR::Use op1Use; + LIR::Use::MakeDummyUse(BlockRange(), op1, &op1Use); + + op1Use.ReplaceWithLclVar(comp); + op1 = op1Use.Def(); + + GenTree* op2 = comp->gtClone(op1); + BlockRange().InsertAfter(op1, op2); + + tmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, NI_AdvSimd_ZeroExtendWideningUpper, simdBaseJitType, 16); + BlockRange().InsertBefore(op2, tmp); + op1 = tmp; + + GenTree* icon = comp->gtNewIconNode(8); + BlockRange().InsertBefore(op2, icon); + + tmp = comp->gtNewSimdBinOpNode(GT_LSH, simdType, op1, icon, CORINFO_TYPE_USHORT, simdSize); + BlockRange().InsertBefore(op2, tmp); + op1 = tmp; + + tmp = comp->gtNewSimdGetLowerNode(TYP_SIMD8, op2, simdBaseJitType, 16); + BlockRange().InsertAfter(op2, tmp); + op2 = tmp; + + tmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, op2, NI_AdvSimd_AddWideningLower, simdBaseJitType, 8); + BlockRange().InsertAfter(op2, tmp); + op1 = tmp; + + simdBaseType = TYP_USHORT; + simdBaseJitType = CORINFO_TYPE_USHORT; + } + + // Sum the elements + + if (!varTypeIsLong(simdBaseType)) + { + if ((simdSize == 8) && ((simdBaseType == TYP_INT) || (simdBaseType == TYP_UINT))) + { + LIR::Use op1Use; + LIR::Use::MakeDummyUse(BlockRange(), op1, &op1Use); + + op1Use.ReplaceWithLclVar(comp); + op1 = op1Use.Def(); + + GenTree* op2 = comp->gtClone(op1); + BlockRange().InsertAfter(op1, op2); + + tmp = + comp->gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, op2, NI_AdvSimd_AddPairwise, simdBaseJitType, simdSize); + BlockRange().InsertAfter(op2, tmp); + op1 = tmp; + } + else + { + tmp = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddAcross, simdBaseJitType, simdSize); + BlockRange().InsertAfter(op1, tmp); + op1 = tmp; + } + } + else if (simdSize == 16) + { + tmp = comp->gtNewSimdHWIntrinsicNode(TYP_SIMD8, op1, NI_AdvSimd_Arm64_AddPairwiseScalar, simdBaseJitType, + simdSize); + BlockRange().InsertAfter(op1, tmp); + op1 = tmp; + } + + if (simdSize == 8) + { + intrinsic = NI_Vector64_ToScalar; + } + else + { + intrinsic = NI_Vector128_ToScalar; + } + + node->gtType = genActualType(simdBaseType); + node->ChangeHWIntrinsicId(intrinsic); + node->SetSimdSize(8); + node->SetSimdBaseJitType(simdBaseJitType); + node->Op(1) = op1; + + if ((simdBaseType != TYP_INT) && (simdBaseType != TYP_UINT)) + { + GenTree* castNode = comp->gtNewCastNode(TYP_INT, node, /* isUnsigned */ true, TYP_INT); + BlockRange().InsertAfter(node, castNode); + + if (parents.Height() > 1) + { + parents.Top(1)->ReplaceOperand(use, castNode); + } + else + { + *use = castNode; + } + + // Adjust the parent stack + assert(parents.Top() == node); + (void)parents.Pop(); + parents.Push(castNode); + } +#elif defined(TARGET_XARCH) + NamedIntrinsic moveMaskIntrinsic = NI_Illegal; + NamedIntrinsic shuffleIntrinsic = NI_Illegal; + + simdBaseJitType = varTypeIsUnsigned(simdBaseType) ? CORINFO_TYPE_UBYTE : CORINFO_TYPE_BYTE; + + // We want to tightly pack the most significant byte of each short/ushort + // and then zero the tightly packed least significant bytes + // + // The most significant bit being set means zero the value + + simd_t simdVal = {}; + + simdVal.u64[0] = 0x0F0D0B0907050301; + simdVal.u64[1] = 0x8080808080808080; + + if (simdSize == 32) + { + // Vector256 works on 2x128-bit lanes, so repeat the same indices for the upper lane + + simdVal.u64[2] = 0x0F0D0B0907050301; + simdVal.u64[3] = 0x8080808080808080; + + shuffleIntrinsic = NI_AVX2_Shuffle; + moveMaskIntrinsic = NI_X86Base_MoveMask; + } + else + { + assert(comp->compIsaSupportedDebugOnly(InstructionSet_SSE42)); + + shuffleIntrinsic = NI_SSE42_Shuffle; + moveMaskIntrinsic = NI_X86Base_MoveMask; + } + + GenTree* op2 = comp->gtNewVconNode(simdType); + memcpy(&op2->AsVecCon()->gtSimdVal, &simdVal, simdSize); + BlockRange().InsertAfter(op1, op2); + + GenTree* tmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, op2, shuffleIntrinsic, simdBaseJitType, simdSize); + BlockRange().InsertAfter(op2, tmp); + op1 = tmp; + + if (simdSize == 32) + { + CorInfoType simdOtherJitType; + + // Since Vector256 is 2x128-bit lanes we need a full width permutation so we get the lower + // 64-bits of each lane next to eachother. The upper bits should be zero, but also don't + // matter so we can also then simplify down to a 128-bit move mask. + + simdOtherJitType = (simdBaseType == TYP_UBYTE) ? CORINFO_TYPE_ULONG : CORINFO_TYPE_LONG; + + GenTree* icon = comp->gtNewIconNode(0xD8); + BlockRange().InsertAfter(op1, icon); + + tmp = comp->gtNewSimdHWIntrinsicNode(simdType, op1, icon, NI_AVX2_Permute4x64, simdOtherJitType, simdSize); + BlockRange().InsertAfter(icon, tmp); + op1 = tmp; + + simdType = TYP_SIMD16; + + tmp = comp->gtNewSimdGetLowerNode(simdType, op1, simdBaseJitType, simdSize); + BlockRange().InsertAfter(op1, tmp); + op1 = tmp; + + simdSize = 16; + } + + node->ChangeHWIntrinsicId(moveMaskIntrinsic); + node->SetSimdSize(simdSize); + node->SetSimdBaseJitType(simdBaseJitType); + node->Op(1) = op1; +#else + unreached(); +#endif +} #endif // FEATURE_HW_INTRINSICS #ifdef TARGET_ARM64 diff --git a/src/runtime/src/coreclr/jit/rationalize.h b/src/runtime/src/coreclr/jit/rationalize.h index b09bb04da5f..a4d18f25f70 100644 --- a/src/runtime/src/coreclr/jit/rationalize.h +++ b/src/runtime/src/coreclr/jit/rationalize.h @@ -63,6 +63,8 @@ class Rationalizer final : public Phase bool ShouldRewriteToNonMaskHWIntrinsic(GenTree* node); #endif // TARGET_XARCH + + void RewriteHWIntrinsicExtractMsb(GenTree** use, Compiler::GenTreeStack& parents); #endif // FEATURE_HW_INTRINSICS #ifdef TARGET_ARM64 diff --git a/src/runtime/src/coreclr/jit/simd.h b/src/runtime/src/coreclr/jit/simd.h index 36164f01761..6f7b191451b 100644 --- a/src/runtime/src/coreclr/jit/simd.h +++ b/src/runtime/src/coreclr/jit/simd.h @@ -56,7 +56,7 @@ struct simd8_t { simd8_t result; - result.u64[0] = 0xFFFFFFFFFFFFFFFF; + result.u64[0] = UINT64_MAX; return result; } @@ -113,9 +113,9 @@ struct simd12_t { simd12_t result; - result.u32[0] = 0xFFFFFFFF; - result.u32[1] = 0xFFFFFFFF; - result.u32[2] = 0xFFFFFFFF; + result.u32[0] = UINT32_MAX; + result.u32[1] = UINT32_MAX; + result.u32[2] = UINT32_MAX; return result; } @@ -322,7 +322,7 @@ struct simdmask_t bool operator==(const simdmask_t& other) const { - return (u64[0] == other.u64[0]); + return GetRawBits() == other.GetRawBits(); } bool operator!=(const simdmask_t& other) const @@ -330,19 +330,25 @@ struct simdmask_t return !(*this == other); } - static simdmask_t AllBitsSet(unsigned elementCount) + static uint64_t GetBitMask(uint32_t elementCount) { assert((elementCount >= 1) && (elementCount <= 64)); - simdmask_t result; if (elementCount == 64) { - result.u64[0] = 0xFFFFFFFFFFFFFFFF; + return UINT64_MAX; } else { - result.u64[0] = (1ULL << elementCount) - 1; + return (1ULL << elementCount) - 1; } + } + + static simdmask_t AllBitsSet(uint32_t elementCount) + { + simdmask_t result; + + result.u64[0] = GetBitMask(elementCount); return result; } @@ -357,6 +363,13 @@ struct simdmask_t return *this == Zero(); } + uint64_t GetRawBits() const + { + uint64_t value; + memcpy(&value, &u64[0], sizeof(uint64_t)); + return value; + } + static simdmask_t Zero() { return {}; @@ -469,7 +482,7 @@ void EvaluateUnaryMask(genTreeOps oper, bool scalar, unsigned simdSize, simdmask } assert((count == 8) || (count == 16) || (count == 32) || (count == 64)); - uint64_t bitMask = static_cast((static_cast(1) << count) - 1); + uint64_t bitMask = simdmask_t::GetBitMask(count); #elif defined(TARGET_ARM64) // For Arm64 we have count total bits to write, but they are sizeof(TBase) bits apart uint64_t bitMask; @@ -509,8 +522,7 @@ void EvaluateUnaryMask(genTreeOps oper, bool scalar, unsigned simdSize, simdmask #error Unsupported platform #endif - uint64_t arg0Value; - memcpy(&arg0Value, &arg0.u64[0], sizeof(simdmask_t)); + uint64_t arg0Value = arg0.GetRawBits(); // We're only considering these bits arg0Value &= bitMask; @@ -582,6 +594,68 @@ inline void EvaluateUnaryMask( } } } + +template +inline void EvaluateExtractMSB(simdmask_t* result, const TSimd& arg0) +{ + uint64_t resultValue = 0; + uint32_t count = sizeof(TSimd) / sizeof(TBase); + + for (uint32_t i = 0; i < count; i++) + { + TBase input0; + memcpy(&input0, &arg0.u8[i * sizeof(TBase)], sizeof(TBase)); + + if (input0 < 0) + { + resultValue |= (static_cast(1) << i); + } + } + + memcpy(&result->u64[0], &resultValue, sizeof(uint64_t)); +} + +template +inline void EvaluateExtractMSB(var_types baseType, simdmask_t* result, const TSimd& arg0) +{ + switch (baseType) + { + case TYP_BYTE: + case TYP_UBYTE: + { + EvaluateExtractMSB(result, arg0); + break; + } + + case TYP_SHORT: + case TYP_USHORT: + { + EvaluateExtractMSB(result, arg0); + break; + } + + case TYP_INT: + case TYP_UINT: + case TYP_FLOAT: + { + EvaluateExtractMSB(result, arg0); + break; + } + + case TYP_LONG: + case TYP_ULONG: + case TYP_DOUBLE: + { + EvaluateExtractMSB(result, arg0); + break; + } + + default: + { + unreached(); + } + } +} #endif // FEATURE_MASKED_HW_INTRINSICS template @@ -1059,7 +1133,7 @@ void EvaluateBinaryMask( } assert((count == 8) || (count == 16) || (count == 32) || (count == 64)); - uint64_t bitMask = static_cast((static_cast(1) << count) - 1); + uint64_t bitMask = simdmask_t::GetBitMask(count); #elif defined(TARGET_ARM64) // For Arm64 we have count total bits to write, but they are sizeof(TBase) bits apart uint64_t bitMask; @@ -1099,11 +1173,8 @@ void EvaluateBinaryMask( #error Unsupported platform #endif - uint64_t arg0Value; - memcpy(&arg0Value, &arg0.u64[0], sizeof(simdmask_t)); - - uint64_t arg1Value; - memcpy(&arg1Value, &arg1.u64[0], sizeof(simdmask_t)); + uint64_t arg0Value = arg0.GetRawBits(); + uint64_t arg1Value = arg1.GetRawBits(); // We're only considering these bits arg0Value &= bitMask; diff --git a/src/runtime/src/coreclr/jit/switchrecognition.cpp b/src/runtime/src/coreclr/jit/switchrecognition.cpp index 6818a6b15b8..163171cc69b 100644 --- a/src/runtime/src/coreclr/jit/switchrecognition.cpp +++ b/src/runtime/src/coreclr/jit/switchrecognition.cpp @@ -42,12 +42,12 @@ PhaseStatus Compiler::optRecognizeAndOptimizeSwitchJumps() modified = true; // Converted switches won't have dominant cases, so we can skip the switch peeling check. - assert(!block->GetSwitchTargets()->bbsHasDominantCase); + assert(!block->GetSwitchTargets()->HasDominantCase()); } else #endif - if (block->KindIs(BBJ_SWITCH) && block->GetSwitchTargets()->bbsHasDominantCase) + if (block->KindIs(BBJ_SWITCH) && block->GetSwitchTargets()->HasDominantCase()) { fgPeelSwitch(block); modified = true; @@ -377,7 +377,12 @@ bool Compiler::optSwitchConvert( FlowEdge* const falseEdge = firstBlock->GetFalseEdge(); // Convert firstBlock to a switch block - firstBlock->SetSwitch(new (this, CMK_BasicBlock) BBswtDesc); + const unsigned jumpCount = static_cast(maxValue - minValue + 1); + assert((jumpCount > 0) && (jumpCount <= SWITCH_MAX_DISTANCE + 1)); + FlowEdge** const jmpTab = + new (this, CMK_FlowEdge) FlowEdge*[2 + jumpCount + 1 /* true/false edges | cases | default case */]; + + firstBlock->SetSwitch(new (this, CMK_BasicBlock) BBswtDesc(jmpTab, 2, jmpTab + 2, jumpCount + 1, true)); firstBlock->bbCodeOffsEnd = lastBlock->bbCodeOffsEnd; firstBlock->lastStmt()->GetRootNode()->ChangeOper(GT_SWITCH); @@ -406,14 +411,7 @@ bool Compiler::optSwitchConvert( blockToRemove = nextBlockToRemove; } - const unsigned jumpCount = static_cast(maxValue - minValue + 1); - assert((jumpCount > 0) && (jumpCount <= SWITCH_MAX_DISTANCE + 1)); - FlowEdge** jmpTab = new (this, CMK_FlowEdge) FlowEdge*[jumpCount + 1 /*default case*/]; - - fgHasSwitch = true; - firstBlock->GetSwitchTargets()->bbsCount = jumpCount + 1; - firstBlock->GetSwitchTargets()->bbsHasDefault = true; - firstBlock->GetSwitchTargets()->bbsDstTab = jmpTab; + fgHasSwitch = true; // Splitting doesn't work well with jump-tables currently opts.compProcedureSplitting = false; @@ -430,7 +428,8 @@ bool Compiler::optSwitchConvert( // Unlink blockIfTrue from firstBlock, we're going to link it again in the loop below. fgRemoveRefPred(trueEdge); - FlowEdge* switchTrueEdge = nullptr; + FlowEdge* switchTrueEdge = nullptr; + FlowEdge** const cases = jmpTab + 2; for (unsigned i = 0; i < jumpCount; i++) { @@ -438,7 +437,7 @@ bool Compiler::optSwitchConvert( const bool isTrue = (bitVector & static_cast(1ULL << i)) != 0; FlowEdge* const newEdge = fgAddRefPred((isTrue ? blockIfTrue : blockIfFalse), firstBlock); - jmpTab[i] = newEdge; + cases[i] = newEdge; if ((switchTrueEdge == nullptr) && isTrue) { @@ -450,11 +449,15 @@ bool Compiler::optSwitchConvert( // Link the 'default' case FlowEdge* const switchDefaultEdge = fgAddRefPred(blockIfFalse, firstBlock); - jmpTab[jumpCount] = switchDefaultEdge; + cases[jumpCount] = switchDefaultEdge; // Fix likelihoods switchDefaultEdge->setLikelihood(falseLikelihood); switchTrueEdge->setLikelihood(1.0 - falseLikelihood); + // Initialize unique successor table + firstBlock->GetSwitchTargets()->GetSuccs()[0] = cases[0]; + firstBlock->GetSwitchTargets()->GetSuccs()[1] = (cases[0] == switchTrueEdge) ? switchDefaultEdge : switchTrueEdge; + return true; } diff --git a/src/runtime/src/coreclr/jit/valuenum.cpp b/src/runtime/src/coreclr/jit/valuenum.cpp index 6cc89a08a81..9bbbfccf208 100644 --- a/src/runtime/src/coreclr/jit/valuenum.cpp +++ b/src/runtime/src/coreclr/jit/valuenum.cpp @@ -7907,6 +7907,79 @@ ValueNum ValueNumStore::EvalHWIntrinsicFunUnary(GenTreeHWIntrinsic* tree, switch (ni) { +#if defined(TARGET_ARM64) + case NI_Vector64_ExtractMostSignificantBits: +#elif defined(TARGET_XARCH) + case NI_Vector256_ExtractMostSignificantBits: + case NI_X86Base_MoveMask: + case NI_AVX_MoveMask: + case NI_AVX2_MoveMask: +#endif + case NI_Vector128_ExtractMostSignificantBits: + { + simdmask_t simdMaskVal; + + switch (simdSize) + { + case 8: + { + simd8_t arg0 = GetConstantSimd8(arg0VN); + EvaluateExtractMSB(baseType, &simdMaskVal, arg0); + break; + } + + case 16: + { + simd16_t arg0 = GetConstantSimd16(arg0VN); + EvaluateExtractMSB(baseType, &simdMaskVal, arg0); + break; + } + +#if defined(TARGET_XARCH) + case 32: + { + simd32_t arg0 = GetConstantSimd32(arg0VN); + EvaluateExtractMSB(baseType, &simdMaskVal, arg0); + break; + } +#endif // TARGET_XARCH + + default: + { + unreached(); + } + } + + uint32_t elemCount = simdSize / genTypeSize(baseType); + uint64_t mask = simdMaskVal.GetRawBits() & simdmask_t::GetBitMask(elemCount); + + assert(varTypeIsInt(type)); + assert(elemCount <= 32); + + return VNForIntCon(static_cast(mask)); + } + +#ifdef TARGET_XARCH + case NI_AVX512_MoveMask: + { + simdmask_t arg0 = GetConstantSimdMask(arg0VN); + + uint32_t elemCount = simdSize / genTypeSize(baseType); + uint64_t mask = arg0.GetRawBits() & simdmask_t::GetBitMask(elemCount); + + if (varTypeIsInt(type)) + { + assert(elemCount <= 32); + return VNForIntCon(static_cast(mask)); + } + else + { + assert(varTypeIsLong(type)); + return VNForLongCon(static_cast(mask)); + } + } +#endif // TARGET_XARCH + #ifdef TARGET_ARM64 case NI_ArmBase_LeadingZeroCount: #else diff --git a/src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets b/src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets index 4e5b53a938b..b655d3879ac 100644 --- a/src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets +++ b/src/runtime/src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.Unix.targets @@ -141,8 +141,8 @@ The .NET Foundation licenses this file to you under the MIT license. - - + + diff --git a/src/runtime/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs b/src/runtime/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs index 6be49af5d42..dd427561f98 100644 --- a/src/runtime/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs +++ b/src/runtime/src/coreclr/tools/Common/JitInterface/CorInfoImpl_generated.cs @@ -1958,21 +1958,6 @@ private static void _getFunctionFixedEntryPoint(IntPtr thisHandle, IntPtr* ppExc } } - [UnmanagedCallersOnly] - private static void* _getMethodSync(IntPtr thisHandle, IntPtr* ppException, CORINFO_METHOD_STRUCT_* ftn, void** ppIndirection) - { - var _this = GetThis(thisHandle); - try - { - return _this.getMethodSync(ftn, ref *ppIndirection); - } - catch (Exception ex) - { - *ppException = _this.AllocException(ex); - return default; - } - } - [UnmanagedCallersOnly] private static CorInfoHelpFunc _getLazyStringLiteralHelper(IntPtr thisHandle, IntPtr* ppException, CORINFO_MODULE_STRUCT_* handle) { @@ -2651,7 +2636,7 @@ private static uint _getJitFlags(IntPtr thisHandle, IntPtr* ppException, CORJIT_ private static IntPtr GetUnmanagedCallbacks() { - void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 179); + void** callbacks = (void**)Marshal.AllocCoTaskMem(sizeof(IntPtr) * 178); callbacks[0] = (delegate* unmanaged)&_isIntrinsic; callbacks[1] = (delegate* unmanaged)&_notifyMethodInfoUsage; @@ -2785,53 +2770,52 @@ private static IntPtr GetUnmanagedCallbacks() callbacks[129] = (delegate* unmanaged)&_getHelperFtn; callbacks[130] = (delegate* unmanaged)&_getFunctionEntryPoint; callbacks[131] = (delegate* unmanaged)&_getFunctionFixedEntryPoint; - callbacks[132] = (delegate* unmanaged)&_getMethodSync; - callbacks[133] = (delegate* unmanaged)&_getLazyStringLiteralHelper; - callbacks[134] = (delegate* unmanaged)&_embedModuleHandle; - callbacks[135] = (delegate* unmanaged)&_embedClassHandle; - callbacks[136] = (delegate* unmanaged)&_embedMethodHandle; - callbacks[137] = (delegate* unmanaged)&_embedFieldHandle; - callbacks[138] = (delegate* unmanaged)&_embedGenericHandle; - callbacks[139] = (delegate* unmanaged)&_getLocationOfThisType; - callbacks[140] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; - callbacks[141] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; - callbacks[142] = (delegate* unmanaged)&_GetCookieForInterpreterCalliSig; - callbacks[143] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; - callbacks[144] = (delegate* unmanaged)&_getJustMyCodeHandle; - callbacks[145] = (delegate* unmanaged)&_GetProfilingHandle; - callbacks[146] = (delegate* unmanaged)&_getCallInfo; - callbacks[147] = (delegate* unmanaged)&_getStaticFieldContent; - callbacks[148] = (delegate* unmanaged)&_getObjectContent; - callbacks[149] = (delegate* unmanaged)&_getStaticFieldCurrentClass; - callbacks[150] = (delegate* unmanaged)&_getVarArgsHandle; - callbacks[151] = (delegate* unmanaged)&_canGetVarArgsHandle; - callbacks[152] = (delegate* unmanaged)&_constructStringLiteral; - callbacks[153] = (delegate* unmanaged)&_emptyStringLiteral; - callbacks[154] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; - callbacks[155] = (delegate* unmanaged)&_GetDelegateCtor; - callbacks[156] = (delegate* unmanaged)&_MethodCompileComplete; - callbacks[157] = (delegate* unmanaged)&_getTailCallHelpers; - callbacks[158] = (delegate* unmanaged)&_getAsyncResumptionStub; - callbacks[159] = (delegate* unmanaged)&_convertPInvokeCalliToCall; - callbacks[160] = (delegate* unmanaged)&_notifyInstructionSetUsage; - callbacks[161] = (delegate* unmanaged)&_updateEntryPointForTailCall; - callbacks[162] = (delegate* unmanaged)&_allocMem; - callbacks[163] = (delegate* unmanaged)&_reserveUnwindInfo; - callbacks[164] = (delegate* unmanaged)&_allocUnwindInfo; - callbacks[165] = (delegate* unmanaged)&_allocGCInfo; - callbacks[166] = (delegate* unmanaged)&_setEHcount; - callbacks[167] = (delegate* unmanaged)&_setEHinfo; - callbacks[168] = (delegate* unmanaged)&_logMsg; - callbacks[169] = (delegate* unmanaged)&_doAssert; - callbacks[170] = (delegate* unmanaged)&_reportFatalError; - callbacks[171] = (delegate* unmanaged)&_getPgoInstrumentationResults; - callbacks[172] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; - callbacks[173] = (delegate* unmanaged)&_recordCallSite; - callbacks[174] = (delegate* unmanaged)&_recordRelocation; - callbacks[175] = (delegate* unmanaged)&_getRelocTypeHint; - callbacks[176] = (delegate* unmanaged)&_getExpectedTargetArchitecture; - callbacks[177] = (delegate* unmanaged)&_getJitFlags; - callbacks[178] = (delegate* unmanaged)&_getSpecialCopyHelper; + callbacks[132] = (delegate* unmanaged)&_getLazyStringLiteralHelper; + callbacks[133] = (delegate* unmanaged)&_embedModuleHandle; + callbacks[134] = (delegate* unmanaged)&_embedClassHandle; + callbacks[135] = (delegate* unmanaged)&_embedMethodHandle; + callbacks[136] = (delegate* unmanaged)&_embedFieldHandle; + callbacks[137] = (delegate* unmanaged)&_embedGenericHandle; + callbacks[138] = (delegate* unmanaged)&_getLocationOfThisType; + callbacks[139] = (delegate* unmanaged)&_getAddressOfPInvokeTarget; + callbacks[140] = (delegate* unmanaged)&_GetCookieForPInvokeCalliSig; + callbacks[141] = (delegate* unmanaged)&_GetCookieForInterpreterCalliSig; + callbacks[142] = (delegate* unmanaged)&_canGetCookieForPInvokeCalliSig; + callbacks[143] = (delegate* unmanaged)&_getJustMyCodeHandle; + callbacks[144] = (delegate* unmanaged)&_GetProfilingHandle; + callbacks[145] = (delegate* unmanaged)&_getCallInfo; + callbacks[146] = (delegate* unmanaged)&_getStaticFieldContent; + callbacks[147] = (delegate* unmanaged)&_getObjectContent; + callbacks[148] = (delegate* unmanaged)&_getStaticFieldCurrentClass; + callbacks[149] = (delegate* unmanaged)&_getVarArgsHandle; + callbacks[150] = (delegate* unmanaged)&_canGetVarArgsHandle; + callbacks[151] = (delegate* unmanaged)&_constructStringLiteral; + callbacks[152] = (delegate* unmanaged)&_emptyStringLiteral; + callbacks[153] = (delegate* unmanaged)&_getFieldThreadLocalStoreID; + callbacks[154] = (delegate* unmanaged)&_GetDelegateCtor; + callbacks[155] = (delegate* unmanaged)&_MethodCompileComplete; + callbacks[156] = (delegate* unmanaged)&_getTailCallHelpers; + callbacks[157] = (delegate* unmanaged)&_getAsyncResumptionStub; + callbacks[158] = (delegate* unmanaged)&_convertPInvokeCalliToCall; + callbacks[159] = (delegate* unmanaged)&_notifyInstructionSetUsage; + callbacks[160] = (delegate* unmanaged)&_updateEntryPointForTailCall; + callbacks[161] = (delegate* unmanaged)&_allocMem; + callbacks[162] = (delegate* unmanaged)&_reserveUnwindInfo; + callbacks[163] = (delegate* unmanaged)&_allocUnwindInfo; + callbacks[164] = (delegate* unmanaged)&_allocGCInfo; + callbacks[165] = (delegate* unmanaged)&_setEHcount; + callbacks[166] = (delegate* unmanaged)&_setEHinfo; + callbacks[167] = (delegate* unmanaged)&_logMsg; + callbacks[168] = (delegate* unmanaged)&_doAssert; + callbacks[169] = (delegate* unmanaged)&_reportFatalError; + callbacks[170] = (delegate* unmanaged)&_getPgoInstrumentationResults; + callbacks[171] = (delegate* unmanaged)&_allocPgoInstrumentationBySchema; + callbacks[172] = (delegate* unmanaged)&_recordCallSite; + callbacks[173] = (delegate* unmanaged)&_recordRelocation; + callbacks[174] = (delegate* unmanaged)&_getRelocTypeHint; + callbacks[175] = (delegate* unmanaged)&_getExpectedTargetArchitecture; + callbacks[176] = (delegate* unmanaged)&_getJitFlags; + callbacks[177] = (delegate* unmanaged)&_getSpecialCopyHelper; return (IntPtr)callbacks; } diff --git a/src/runtime/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt b/src/runtime/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt index 7b5f8a7d79f..18f4498a848 100644 --- a/src/runtime/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt +++ b/src/runtime/src/coreclr/tools/Common/JitInterface/ThunkGenerator/ThunkInput.txt @@ -298,7 +298,6 @@ FUNCTIONS void getHelperFtn (CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP* pNativeEntrypoint, CORINFO_METHOD_HANDLE *pMethod); void getFunctionEntryPoint(CORINFO_METHOD_HANDLE ftn, REF_CORINFO_CONST_LOOKUP pResult, CORINFO_ACCESS_FLAGS accessFlags); void getFunctionFixedEntryPoint(CORINFO_METHOD_HANDLE ftn, bool isUnsafeFunctionPointer, REF_CORINFO_CONST_LOOKUP pResult); - void* getMethodSync(CORINFO_METHOD_HANDLE ftn, void **ppIndirection); CorInfoHelpFunc getLazyStringLiteralHelper(CORINFO_MODULE_HANDLE handle); CORINFO_MODULE_HANDLE embedModuleHandle(CORINFO_MODULE_HANDLE handle, void **ppIndirection); CORINFO_CLASS_HANDLE embedClassHandle(CORINFO_CLASS_HANDLE handle, void **ppIndirection); diff --git a/src/runtime/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs b/src/runtime/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs index 3e3c1762f18..afa3677e648 100644 --- a/src/runtime/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs +++ b/src/runtime/src/coreclr/tools/aot/ILCompiler.ReadyToRun/JitInterface/CorInfoImpl.ReadyToRun.cs @@ -2954,11 +2954,6 @@ private void getMethodVTableOffset(CORINFO_METHOD_STRUCT_* method, ref uint offs private void expandRawHandleIntrinsic(ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_GENERICHANDLE_RESULT pResult) { throw new NotImplementedException("expandRawHandleIntrinsic"); } - private void* getMethodSync(CORINFO_METHOD_STRUCT_* ftn, ref void* ppIndirection) - { - throw new RequiresRuntimeJitException($"{MethodBeingCompiled} -> {nameof(getMethodSync)}"); - } - private byte[] _bbCounts; partial void findKnownBBCountBlock(ref BlockType blockType, void* location, ref int offset) diff --git a/src/runtime/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs b/src/runtime/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs index 90d54ed2bd7..1cd7c8503a1 100644 --- a/src/runtime/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs +++ b/src/runtime/src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs @@ -1894,26 +1894,6 @@ private uint getMethodAttribs(CORINFO_METHOD_STRUCT_* ftn) return getMethodAttribsInternal(HandleToObject(ftn)); } - private void* getMethodSync(CORINFO_METHOD_STRUCT_* ftn, ref void* ppIndirection) - { - MethodDesc method = HandleToObject(ftn); - TypeDesc type = method.OwningType; - ISymbolNode methodSync = _compilation.NecessaryTypeSymbolIfPossible(type); - - void* result = (void*)ObjectToHandle(methodSync); - - if (methodSync.RepresentsIndirectionCell) - { - ppIndirection = result; - return null; - } - else - { - ppIndirection = null; - return result; - } - } - private unsafe HRESULT allocPgoInstrumentationBySchema(CORINFO_METHOD_STRUCT_* ftnHnd, PgoInstrumentationSchema* pSchema, uint countSchemaItems, byte** pInstrumentationData) { throw new NotImplementedException("allocPgoInstrumentationBySchema"); diff --git a/src/runtime/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h b/src/runtime/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h index f72f9cdeef2..6376292d538 100644 --- a/src/runtime/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h +++ b/src/runtime/src/coreclr/tools/aot/jitinterface/jitinterface_generated.h @@ -143,7 +143,6 @@ struct JitInterfaceCallbacks void (* getHelperFtn)(void * thisHandle, CorInfoExceptionClass** ppException, CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP* pNativeEntrypoint, CORINFO_METHOD_HANDLE* pMethod); void (* getFunctionEntryPoint)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, CORINFO_CONST_LOOKUP* pResult, CORINFO_ACCESS_FLAGS accessFlags); void (* getFunctionFixedEntryPoint)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, bool isUnsafeFunctionPointer, CORINFO_CONST_LOOKUP* pResult); - void* (* getMethodSync)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_METHOD_HANDLE ftn, void** ppIndirection); CorInfoHelpFunc (* getLazyStringLiteralHelper)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE handle); CORINFO_MODULE_HANDLE (* embedModuleHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_MODULE_HANDLE handle, void** ppIndirection); CORINFO_CLASS_HANDLE (* embedClassHandle)(void * thisHandle, CorInfoExceptionClass** ppException, CORINFO_CLASS_HANDLE handle, void** ppIndirection); @@ -1480,16 +1479,6 @@ class JitInterfaceWrapper : public ICorJitInfo if (pException != nullptr) throw pException; } - virtual void* getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection) -{ - CorInfoExceptionClass* pException = nullptr; - void* temp = _callbacks->getMethodSync(_thisHandle, &pException, ftn, ppIndirection); - if (pException != nullptr) throw pException; - return temp; -} - virtual CorInfoHelpFunc getLazyStringLiteralHelper( CORINFO_MODULE_HANDLE handle) { diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h index b65429f3153..595f376ff73 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/lwmlist.h @@ -115,7 +115,6 @@ LWM(HaveSameMethodDefinition, DLDL, DWORD) LWM(GetTypeDefinition, DWORDLONG, DWORDLONG) LWM(GetMethodNameFromMetadata, Agnostic_CORINFO_METHODNAME_TOKENin, Agnostic_CORINFO_METHODNAME_TOKENout) LWM(GetMethodSig, DLDL, Agnostic_CORINFO_SIG_INFO) -LWM(GetMethodSync, DWORDLONG, DLDL) LWM(GetMethodVTableOffset, DWORDLONG, DDD) LWM(GetNewArrHelper, DWORDLONG, DWORD) LWM(GetNewHelper, DWORDLONG, DDD) diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp index bfdab057de4..152e1299e89 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp @@ -2396,7 +2396,7 @@ void MethodContext::recGetHelperFtn(CorInfoHelpFunc ftnNum, CORINFO_CONST_LOOKUP } void MethodContext::dmpGetHelperFtn(DWORD key, Agnostic_GetHelperFtn value) { - printf("GetHelperFtn key ftn-%u nativeEntrypoint {%s}, helperMethod-%016" PRIX64 "", key, + printf("GetHelperFtn key ftn-%u nativeEntrypoint {%s}, helperMethod-%016" PRIX64 "", key, SpmiDumpHelper::DumpAgnostic_CORINFO_CONST_LOOKUP(value.helperLookup).c_str(), value.helperMethod); } @@ -5504,37 +5504,6 @@ void MethodContext::repFindCallSiteSig(CORINFO_MODULE_HANDLE module, *sig = SpmiRecordsHelper::Restore_CORINFO_SIG_INFO(value, FindCallSiteSig, SigInstHandleMap, cr->getOrCreateMemoryTracker()); } -void MethodContext::recGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection, void* result) -{ - if (GetMethodSync == nullptr) - GetMethodSync = new LightWeightMap(); - DLDL value; - if (ppIndirection != nullptr) - value.A = CastPointer(*ppIndirection); - else - value.A = 0; - value.B = CastPointer(result); - - DWORDLONG key = CastHandle(ftn); - GetMethodSync->Add(key, value); - DEBUG_REC(dmpGetMethodSync(key, value)); -} -void MethodContext::dmpGetMethodSync(DWORDLONG key, DLDL value) -{ - printf("GetMethodSync key %016" PRIX64 ", value pp-%016" PRIX64 " res-%016" PRIX64 "", key, value.A, value.B); -} -void* MethodContext::repGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection) -{ - DWORDLONG key = CastHandle(ftn); - DLDL value = LookupByKeyOrMiss(GetMethodSync, key, ": key %016" PRIX64 "", key); - - DEBUG_REP(dmpGetMethodSync(key, value)); - - if (ppIndirection != nullptr) - *ppIndirection = (void*)value.A; - return (void*)value.B; -} - void MethodContext::recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection, CORINFO_VARARGS_HANDLE result) { if (GetVarArgsHandle == nullptr) diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h index 06c1c1e33bd..d7ce4ed4069 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontext.h @@ -460,13 +460,13 @@ class MethodContext void dmpGetUnboxedEntry(DWORDLONG key, DLD value); CORINFO_METHOD_HANDLE repGetUnboxedEntry(CORINFO_METHOD_HANDLE ftn, bool* requiresInstMethodTableArg); - void recGetInstantiatedEntry(CORINFO_METHOD_HANDLE ftn, + void recGetInstantiatedEntry(CORINFO_METHOD_HANDLE ftn, CORINFO_METHOD_HANDLE methodHandle, CORINFO_CLASS_HANDLE classHandle, CORINFO_METHOD_HANDLE result); void dmpGetInstantiatedEntry(DWORDLONG key, const Agnostic_GetInstantiatedEntryResult& value); - CORINFO_METHOD_HANDLE repGetInstantiatedEntry(CORINFO_METHOD_HANDLE ftn, - CORINFO_METHOD_HANDLE* methodHandle, + CORINFO_METHOD_HANDLE repGetInstantiatedEntry(CORINFO_METHOD_HANDLE ftn, + CORINFO_METHOD_HANDLE* methodHandle, CORINFO_CLASS_HANDLE* classHandle); void recGetDefaultComparerClass(CORINFO_CLASS_HANDLE cls, CORINFO_CLASS_HANDLE result); @@ -713,10 +713,6 @@ class MethodContext CORINFO_CONTEXT_HANDLE context, CORINFO_SIG_INFO* sig); - void recGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection, void* result); - void dmpGetMethodSync(DWORDLONG key, DLDL value); - void* repGetMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection); - void recGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection, CORINFO_VARARGS_HANDLE result); void dmpGetVarArgsHandle(const GetVarArgsHandleValue& key, DLDL value); CORINFO_VARARGS_HANDLE repGetVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection); @@ -1068,7 +1064,7 @@ enum mcPackets Packet_GetMethodHash = 73, Packet_GetMethodInfo = 74, Packet_GetMethodSig = 76, - Packet_GetMethodSync = 77, + // Packet_GetMethodSync = 77, Packet_GetMethodVTableOffset = 78, Packet_GetNewArrHelper = 79, Packet_GetNewHelper = 80, diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp index 529d8260b67..3165ac8ab73 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.cpp @@ -94,7 +94,7 @@ MethodContextReader::MethodContextReader( , Offset(offset) , Increment(increment) { - this->mutex = CreateMutexW(NULL, FALSE, nullptr); + minipal_mutex_init(&this->mutex); std::string tocFileName, mchFileName; @@ -140,20 +140,19 @@ MethodContextReader::~MethodContextReader() CloseHandle(this->fileHandle); } - CloseHandle(this->mutex); - + minipal_mutex_destroy(&this->mutex); CleanExcludedMethods(); } bool MethodContextReader::AcquireLock() { - DWORD res = WaitForSingleObject(this->mutex, INFINITE); - return (res == WAIT_OBJECT_0); + minipal_mutex_enter(&this->mutex); + return true; } void MethodContextReader::ReleaseLock() { - ReleaseMutex(this->mutex); + minipal_mutex_leave(&this->mutex); } bool MethodContextReader::atEof() @@ -418,7 +417,7 @@ bool MethodContextReader::hasTOC() bool MethodContextReader::isValid() { - return this->fileHandle != INVALID_HANDLE_VALUE && this->mutex != INVALID_HANDLE_VALUE; + return this->fileHandle != INVALID_HANDLE_VALUE; } // Return a measure of "progress" through the method contexts, as follows: @@ -640,7 +639,7 @@ void MethodContextReader::Reset(const int* newIndexes, int newIndexCount) int64_t pos = 0; BOOL result = SetFilePointerEx(fileHandle, *(PLARGE_INTEGER)&pos, NULL, FILE_BEGIN); assert(result); - + Indexes = newIndexes; IndexCount = newIndexCount; curIndexPos = 0; diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h index df3ca7b3165..f5ef48009b8 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shared/methodcontextreader.h @@ -10,6 +10,7 @@ #include "methodcontext.h" #include "tocfile.h" +#include struct MethodContextBuffer { @@ -56,7 +57,7 @@ class MethodContextReader int curMCIndex; // The synchronization mutex - HANDLE mutex; + minipal_mutex mutex; bool AcquireLock(); void ReleaseLock(); diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp index eab692b4d37..bc2fc013151 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-collector/icorjitinfo.cpp @@ -1504,15 +1504,6 @@ void interceptor_ICJI::getFunctionFixedEntryPoint( mc->recGetFunctionFixedEntryPoint(ftn, pResult); } -// get the synchronization handle that is passed to monXstatic function -void* interceptor_ICJI::getMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection) -{ - mc->cr->AddCall("getMethodSync"); - void* temp = original_ICorJitInfo->getMethodSync(ftn, ppIndirection); - mc->recGetMethodSync(ftn, ppIndirection, temp); - return temp; -} - // These entry points must be called if a handle is being embedded in // the code to be passed to a JIT helper function. (as opposed to just // being passed back into the ICorInfo interface.) diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp index ffcf2dc7496..615f8c9dca1 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-counter/icorjitinfo_generated.cpp @@ -1069,14 +1069,6 @@ void interceptor_ICJI::getFunctionFixedEntryPoint( original_ICorJitInfo->getFunctionFixedEntryPoint(ftn, isUnsafeFunctionPointer, pResult); } -void* interceptor_ICJI::getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection) -{ - mcs->AddCall("getMethodSync"); - return original_ICorJitInfo->getMethodSync(ftn, ppIndirection); -} - CorInfoHelpFunc interceptor_ICJI::getLazyStringLiteralHelper( CORINFO_MODULE_HANDLE handle) { diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp index 718959681da..c4caa76a895 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi-shim-simple/icorjitinfo_generated.cpp @@ -937,13 +937,6 @@ void interceptor_ICJI::getFunctionFixedEntryPoint( original_ICorJitInfo->getFunctionFixedEntryPoint(ftn, isUnsafeFunctionPointer, pResult); } -void* interceptor_ICJI::getMethodSync( - CORINFO_METHOD_HANDLE ftn, - void** ppIndirection) -{ - return original_ICorJitInfo->getMethodSync(ftn, ppIndirection); -} - CorInfoHelpFunc interceptor_ICJI::getLazyStringLiteralHelper( CORINFO_MODULE_HANDLE handle) { diff --git a/src/runtime/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp b/src/runtime/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp index fafda8ea9fd..c40cd89f854 100644 --- a/src/runtime/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp +++ b/src/runtime/src/coreclr/tools/superpmi/superpmi/icorjitinfo.cpp @@ -1299,13 +1299,6 @@ void MyICJI::getFunctionFixedEntryPoint( jitInstance->mc->repGetFunctionFixedEntryPoint(ftn, isUnsafeFunctionPointer, pResult); } -// get the synchronization handle that is passed to monXstatic function -void* MyICJI::getMethodSync(CORINFO_METHOD_HANDLE ftn, void** ppIndirection) -{ - jitInstance->mc->cr->AddCall("getMethodSync"); - return jitInstance->mc->repGetMethodSync(ftn, ppIndirection); -} - // These entry points must be called if a handle is being embedded in // the code to be passed to a JIT helper function. (as opposed to just // being passed back into the ICorInfo interface.) diff --git a/src/runtime/src/coreclr/utilcode/log.cpp b/src/runtime/src/coreclr/utilcode/log.cpp index e56255f8362..296757812e6 100644 --- a/src/runtime/src/coreclr/utilcode/log.cpp +++ b/src/runtime/src/coreclr/utilcode/log.cpp @@ -33,7 +33,7 @@ static DWORD LogFlags = 0; static CQuickWSTR szLogFileName; static HANDLE LogFileHandle = INVALID_HANDLE_VALUE; -static volatile HANDLE LogFileMutex = 0; +static minipal_mutex* volatile LogFileMutex = nullptr; static DWORD LogFacilityMask = LF_ALL; static DWORD LogFacilityMask2 = 0; static DWORD LogVMLevel = LL_INFO100; @@ -156,11 +156,9 @@ VOID EnterLogLock() // rather hard to care about this, as we LOG all over the place. CONTRACT_VIOLATION(TakesLockViolation); - if(LogFileMutex != 0) + if (LogFileMutex != nullptr) { - DWORD status; - status = WaitForSingleObjectEx(LogFileMutex, INFINITE, FALSE); - _ASSERTE(WAIT_OBJECT_0 == status); + minipal_mutex_enter(LogFileMutex); } } @@ -169,11 +167,9 @@ VOID LeaveLogLock() STATIC_CONTRACT_NOTHROW; STATIC_CONTRACT_GC_NOTRIGGER; - if(LogFileMutex != 0) + if (LogFileMutex != nullptr) { - BOOL success; - success = ReleaseMutex(LogFileMutex); - _ASSERTE(success); + minipal_mutex_leave(LogFileMutex); } } @@ -185,11 +181,14 @@ VOID InitializeLogging() if (bLoggingInitialized) return; - HANDLE mutex = CreateMutex(NULL, FALSE, NULL); - _ASSERTE(mutex != 0); - if (InterlockedCompareExchangeT(&LogFileMutex, mutex, 0) != 0) + minipal_mutex* mutex = new minipal_mutex; + bool success = minipal_mutex_init(mutex); + _ASSERTE(success); + + if (InterlockedCompareExchangeT(&LogFileMutex, mutex, nullptr) != nullptr) { - CloseHandle(mutex); + minipal_mutex_destroy(mutex); + delete mutex; } EnterLogLock(); diff --git a/src/runtime/src/coreclr/vm/appdomain.hpp b/src/runtime/src/coreclr/vm/appdomain.hpp index 5e74fd4e7c8..85a87d4ff82 100644 --- a/src/runtime/src/coreclr/vm/appdomain.hpp +++ b/src/runtime/src/coreclr/vm/appdomain.hpp @@ -423,7 +423,6 @@ class LoadLevelLimiter final enum { - ATTACH_ASSEMBLY_LOAD = 0x1, ATTACH_MODULE_LOAD = 0x2, ATTACH_CLASS_LOAD = 0x4, diff --git a/src/runtime/src/coreclr/vm/arm64/asmhelpers.S b/src/runtime/src/coreclr/vm/arm64/asmhelpers.S index b4a87823304..5a00639e6af 100644 --- a/src/runtime/src/coreclr/vm/arm64/asmhelpers.S +++ b/src/runtime/src/coreclr/vm/arm64/asmhelpers.S @@ -695,11 +695,11 @@ NESTED_ENTRY InterpreterStub, _TEXT, NoHandler #endif INLINE_GETTHREAD x20 // thrashes x0 on Apple OSes (and possibly other arg registers on other Unixes) - ldr x11, [x20, #OFFSETOF__Thread__m_pInterpThreadContext] + ldr x11, [x20, #OFFSETOF__Thread__m_pInterpThreadContext] cbnz x11, LOCAL_LABEL(HaveInterpThreadContext) #ifdef TARGET_APPLE - // There Thread::GetInterpThreadContext can destroy all argument registers, so we + // There Thread::GetInterpThreadContext can destroy all argument registers, so we // need to save them. For non-Apple, they have been already saved in the PROLOG_WITH_TRANSITION_BLOCK // Restore x0 thrashed by the INLINE_GETTHREAD mov x0, x21 @@ -887,6 +887,30 @@ NESTED_ENTRY InterpreterStubRet4Float, _TEXT, NoHandler EPILOG_RETURN NESTED_END InterpreterStubRet4Float, _TEXT +NESTED_ENTRY InterpreterStubRetVector64, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_NO_FP_INDEXED fp, lr, -16 + // The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 // the IR bytecode pointer + mov x2, xzr + bl C_FUNC(ExecuteInterpretedMethod) + ldr d0, [x0] + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 16 + EPILOG_RETURN +NESTED_END InterpreterStubRetVector64, _TEXT + +NESTED_ENTRY InterpreterStubRetVector128, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_NO_FP_INDEXED fp, lr, -16 + // The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 // the IR bytecode pointer + mov x2, xzr + bl C_FUNC(ExecuteInterpretedMethod) + ldr q0, [x0] + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 16 + EPILOG_RETURN +NESTED_END InterpreterStubRetVector128, _TEXT + // Copy arguments from the processor stack to the interpreter stack // The CPU stack slots are aligned to pointer size. @@ -1834,4 +1858,42 @@ NESTED_ENTRY CallJittedMethodRet4Float, _TEXT, NoHandler EPILOG_RETURN NESTED_END CallJittedMethodRet4Float, _TEXT +// X0 - routines array +// X1 - interpreter stack args location +// X2 - interpreter stack return value location +// X3 - stack arguments size (properly aligned) +NESTED_ENTRY CallJittedMethodRetVector64, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -32 + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str d0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 32 + EPILOG_RETURN +NESTED_END CallJittedMethodRetVector64, _TEXT + +// X0 - routines array +// X1 - interpreter stack args location +// X2 - interpreter stack return value location +// X3 - stack arguments size (properly aligned) +NESTED_ENTRY CallJittedMethodRetVector128, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -32 + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str q0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 32 + EPILOG_RETURN +NESTED_END CallJittedMethodRetVector128, _TEXT + #endif // FEATURE_INTERPRETER diff --git a/src/runtime/src/coreclr/vm/arm64/asmhelpers.asm b/src/runtime/src/coreclr/vm/arm64/asmhelpers.asm index 9d2f8ee9555..f5de9e3488c 100644 --- a/src/runtime/src/coreclr/vm/arm64/asmhelpers.asm +++ b/src/runtime/src/coreclr/vm/arm64/asmhelpers.asm @@ -1240,6 +1240,30 @@ HaveInterpThreadContext EPILOG_RETURN NESTED_END InterpreterStubRet4Float + NESTED_ENTRY InterpreterStubRetVector64 + PROLOG_SAVE_REG_PAIR fp, lr, #-16! + ; The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 ; the IR bytecode pointer + mov x2, xzr + bl ExecuteInterpretedMethod + ldr d0, [x0] + EPILOG_RESTORE_REG_PAIR fp, lr, #16! + EPILOG_RETURN + NESTED_END InterpreterStubRetVector64 + + NESTED_ENTRY InterpreterStubRetVector128 + PROLOG_SAVE_REG_PAIR fp, lr, #-16! + ; The +16 is for the fp, lr above + add x0, sp, #__PWTB_TransitionBlock + 16 + mov x1, x19 ; the IR bytecode pointer + mov x2, xzr + bl ExecuteInterpretedMethod + ldr q0, [x0] + EPILOG_RESTORE_REG_PAIR fp, lr, #16! + EPILOG_RETURN + NESTED_END InterpreterStubRetVector128 + ; Routines for passing value type arguments by reference in general purpose registers X0..X7 ; from native code to the interpreter @@ -1259,7 +1283,7 @@ StoreCopyLoop ldr x11, [x10], #8 EPILOG_BRANCH_REG x11 LEAF_END Store_Stack - + LEAF_ENTRY Load_Stack_Ref ldr w11, [x10], #4 ; SP offset ldr w12, [x10], #4 ; size of the value type @@ -2117,6 +2141,44 @@ CopyLoop EPILOG_RETURN NESTED_END CallJittedMethodRet4Float + ; X0 - routines array + ; X1 - interpreter stack args location + ; X2 - interpreter stack return value location + ; X3 - stack arguments size (properly aligned) + NESTED_ENTRY CallJittedMethodRetVector64 + PROLOG_SAVE_REG_PAIR fp, lr, #-32! + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str d0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR fp, lr, #32! + EPILOG_RETURN + NESTED_END CallJittedMethodRetVector64 + + ; X0 - routines array + ; X1 - interpreter stack args location + ; X2 - interpreter stack return value location + ; X3 - stack arguments size (properly aligned) + NESTED_ENTRY CallJittedMethodRetVector128 + PROLOG_SAVE_REG_PAIR fp, lr, #-32! + str x2, [sp, #16] + sub sp, sp, x3 + mov x10, x0 + mov x9, x1 + ldr x11, [x10], #8 + blr x11 + ldr x2, [sp, #16] + str q0, [x2] + EPILOG_STACK_RESTORE + EPILOG_RESTORE_REG_PAIR fp, lr, #32! + EPILOG_RETURN + NESTED_END CallJittedMethodRetVector128 + #endif // FEATURE_INTERPRETER ; Must be at very end of file diff --git a/src/runtime/src/coreclr/vm/assembly.cpp b/src/runtime/src/coreclr/vm/assembly.cpp index 95fd73a73ad..cf6e0834dcb 100644 --- a/src/runtime/src/coreclr/vm/assembly.cpp +++ b/src/runtime/src/coreclr/vm/assembly.cpp @@ -2365,7 +2365,7 @@ void Assembly::DeliverSyncEvents() SetShouldNotifyDebugger(); // Still work to do even if no debugger is attached. - NotifyDebuggerLoad(ATTACH_ASSEMBLY_LOAD, FALSE); + NotifyDebuggerLoad(ATTACH_MODULE_LOAD, FALSE); } #endif // DEBUGGING_SUPPORTED @@ -2488,16 +2488,7 @@ BOOL Assembly::NotifyDebuggerLoad(int flags, BOOL attaching) } // There is still work we need to do even when no debugger is attached. - if (flags & ATTACH_ASSEMBLY_LOAD) - { - if (ShouldNotifyDebugger()) - { - g_pDebugInterface->LoadAssembly(GetDomainAssembly()); - } - result = TRUE; - } - - if(this->ShouldNotifyDebugger()) + if(this->ShouldNotifyDebugger() && !(flags & ATTACH_MODULE_LOAD)) { result = result || this->GetModule()->NotifyDebuggerLoad(GetDomainAssembly(), flags, attaching); diff --git a/src/runtime/src/coreclr/vm/callstubgenerator.cpp b/src/runtime/src/coreclr/vm/callstubgenerator.cpp index bfc3931e0e0..be815aaf7e6 100644 --- a/src/runtime/src/coreclr/vm/callstubgenerator.cpp +++ b/src/runtime/src/coreclr/vm/callstubgenerator.cpp @@ -1090,6 +1090,8 @@ extern "C" void CallJittedMethodRetFloat(PCODE *routines, int8_t*pArgs, int8_t*p extern "C" void CallJittedMethodRet2Float(PCODE *routines, int8_t*pArgs, int8_t*pRet, int totalStackSize); extern "C" void CallJittedMethodRet3Float(PCODE *routines, int8_t*pArgs, int8_t*pRet, int totalStackSize); extern "C" void CallJittedMethodRet4Float(PCODE *routines, int8_t*pArgs, int8_t*pRet, int totalStackSize); +extern "C" void CallJittedMethodRetVector64(PCODE *routines, int8_t *pArgs, int8_t *pRet, int totalStackSize); +extern "C" void CallJittedMethodRetVector128(PCODE *routines, int8_t *pArgs, int8_t *pRet, int totalStackSize); extern "C" void InterpreterStubRet2I8(); extern "C" void InterpreterStubRet2Double(); extern "C" void InterpreterStubRet3Double(); @@ -1098,6 +1100,8 @@ extern "C" void InterpreterStubRetFloat(); extern "C" void InterpreterStubRet2Float(); extern "C" void InterpreterStubRet3Float(); extern "C" void InterpreterStubRet4Float(); +extern "C" void InterpreterStubRetVector64(); +extern "C" void InterpreterStubRetVector128(); #endif // TARGET_ARM64 #if LOG_COMPUTE_CALL_STUB @@ -1154,6 +1158,10 @@ CallStubHeader::InvokeFunctionPtr CallStubGenerator::GetInvokeFunctionPtr(CallSt INVOKE_FUNCTION_PTR(CallJittedMethodRet3Float); case ReturnType4Float: INVOKE_FUNCTION_PTR(CallJittedMethodRet4Float); + case ReturnTypeVector64: + INVOKE_FUNCTION_PTR(CallJittedMethodRetVector64); + case ReturnTypeVector128: + INVOKE_FUNCTION_PTR(CallJittedMethodRetVector128); #endif // TARGET_ARM64 default: _ASSERTE(!"Unexpected return type for interpreter stub"); @@ -1215,6 +1223,10 @@ PCODE CallStubGenerator::GetInterpreterReturnTypeHandler(CallStubGenerator::Retu RETURN_TYPE_HANDLER(InterpreterStubRet3Float); case ReturnType4Float: RETURN_TYPE_HANDLER(InterpreterStubRet4Float); + case ReturnTypeVector64: + RETURN_TYPE_HANDLER(InterpreterStubRetVector64); + case ReturnTypeVector128: + RETURN_TYPE_HANDLER(InterpreterStubRetVector128); #endif // TARGET_ARM64 default: _ASSERTE(!"Unexpected return type for interpreter stub"); @@ -1417,23 +1429,8 @@ void CallStubGenerator::ComputeCallStub(MetaSig &sig, PCODE *pRoutines) #endif // The "this" argument register is not enumerated by the arg iterator, so // we need to "inject" it here. -#if defined(TARGET_WINDOWS) && defined(TARGET_AMD64) - if (argIt.HasRetBuffArg()) - { -#if LOG_COMPUTE_CALL_STUB - printf("argIt.HasRetBuffArg() on WINDOWS AMD64\n"); -#endif - // The return buffer on Windows AMD64 is passed in the first argument register, so the - // "this" argument is be passed in the second argument register. - m_r1 = 1; - m_r2 = 1; - } - else -#endif // TARGET_WINDOWS && TARGET_AMD64 - { - // The "this" pointer is passed in the first argument register. - m_r1 = 0; - } + // CLR ABI specifies that unlike the native Windows x64 calling convention, it is passed in the first argument register. + m_r1 = 0; } if (argIt.HasParamType()) @@ -1724,7 +1721,7 @@ CallStubGenerator::ReturnType CallStubGenerator::GetReturnType(ArgIterator *pArg } #else return ReturnTypeBuff; -#endif +#endif } else { @@ -1842,8 +1839,30 @@ CallStubGenerator::ReturnType CallStubGenerator::GetReturnType(ArgIterator *pArg break; } break; +#ifdef FEATURE_SIMD + case CORINFO_HFA_ELEM_VECTOR64: + switch (thReturnValueType.GetSize()) + { + case 8: + return ReturnTypeVector64; + default: + _ASSERTE(!"Unsupported Vector64 HFA size"); + break; + } + break; + case CORINFO_HFA_ELEM_VECTOR128: + switch (thReturnValueType.GetSize()) + { + case 16: + return ReturnTypeVector128; + default: + _ASSERTE(!"Unsupported Vector128 HFA size"); + break; + } + break; +#endif default: - _ASSERTE(!"HFA types other than float and double are not supported yet"); + _ASSERTE(!"HFA type is not supported"); break; } } diff --git a/src/runtime/src/coreclr/vm/callstubgenerator.h b/src/runtime/src/coreclr/vm/callstubgenerator.h index 9f628f6ac08..55ef6911480 100644 --- a/src/runtime/src/coreclr/vm/callstubgenerator.h +++ b/src/runtime/src/coreclr/vm/callstubgenerator.h @@ -83,7 +83,9 @@ class CallStubGenerator ReturnTypeFloat, ReturnType2Float, ReturnType3Float, - ReturnType4Float + ReturnType4Float, + ReturnTypeVector64, + ReturnTypeVector128 #endif // TARGET_ARM64 }; diff --git a/src/runtime/src/coreclr/vm/codeman.h b/src/runtime/src/coreclr/vm/codeman.h index 9720f029e30..1be9d9ce96d 100644 --- a/src/runtime/src/coreclr/vm/codeman.h +++ b/src/runtime/src/coreclr/vm/codeman.h @@ -1980,9 +1980,7 @@ class EECodeGenManager : public IJitManager // must hold critical section to access this structure. CUnorderedArray m_DomainCodeHeaps; CUnorderedArray m_DynamicDomainCodeHeaps; -#ifndef DACCESS_COMPILE CUnorderedArray m_delayUnload; -#endif // !DACCESS_COMPILE protected: Crst m_CodeHeapLock; diff --git a/src/runtime/src/coreclr/vm/dbginterface.h b/src/runtime/src/coreclr/vm/dbginterface.h index 0b2eadf4479..23fec81a347 100644 --- a/src/runtime/src/coreclr/vm/dbginterface.h +++ b/src/runtime/src/coreclr/vm/dbginterface.h @@ -299,14 +299,6 @@ class DebugInterface virtual HRESULT UpdateAppDomainEntryInIPC (AppDomain *pAppDomain) = 0; - // Called when an assembly is being loaded into an AppDomain. - // This includes when a domain neutral assembly is loaded into a new AppDomain. - // This is called only when a debugger is attached, and will occur after the - // related AddAppDomainToIPCBlock call and before any LoadModule or - // LoadClass calls for this assembly. - virtual void LoadAssembly(DomainAssembly * pDomainAssembly) = 0; // the assembly being loaded - - // Called for all assemblies in an AppDomain when the AppDomain is unloaded. // This includes domain neutral assemblies that are also loaded into other domains. // This is called only when a debugger is attached, and will occur after all UnloadClass diff --git a/src/runtime/src/coreclr/vm/interpexec.cpp b/src/runtime/src/coreclr/vm/interpexec.cpp index 927bd812a4a..ea0a3509320 100644 --- a/src/runtime/src/coreclr/vm/interpexec.cpp +++ b/src/runtime/src/coreclr/vm/interpexec.cpp @@ -162,14 +162,23 @@ static OBJECTREF CreateMultiDimArray(MethodTable* arrayClass, int8_t* stack, int #define LOCAL_VAR(offset,type) (*LOCAL_VAR_ADDR(offset, type)) #define NULL_CHECK(o) do { if ((o) == NULL) { COMPlusThrow(kNullReferenceException); } } while (0) -template static THelper GetPossiblyIndirectHelper(void* dataItem) +template static THelper GetPossiblyIndirectHelper(const InterpMethod *pMethod, int32_t _data) { - size_t helperDirectOrIndirect = (size_t)dataItem; - if (helperDirectOrIndirect & INTERP_DIRECT_HELPER_TAG) - // Clear the direct flag and then raise the thumb bit as needed - return (THelper)PINSTRToPCODE((TADDR)(helperDirectOrIndirect & ~INTERP_DIRECT_HELPER_TAG)); - else - return *(THelper *)helperDirectOrIndirect; + InterpHelperData data; + memcpy(&data, &_data, sizeof(int32_t)); + + void *addr = pMethod->pDataItems[data.addressDataItemIndex]; + switch (data.accessType) { + case IAT_VALUE: + return (THelper)addr; + case IAT_PVALUE: + return *(THelper *)addr; + case IAT_PPVALUE: + return **(THelper **)addr; + default: + COMPlusThrowHR(COR_E_EXECUTIONENGINE); + return (THelper)nullptr; + } } // At present our behavior for float to int conversions is to perform a saturating conversion down to either 32 or 64 bits @@ -1695,7 +1704,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_P: { - HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[2]]); + HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod, ip[2]); void* helperArg = pMethod->pDataItems[ip[3]]; LOCAL_VAR(ip[1], void*) = helperFtn(helperArg); @@ -1705,7 +1714,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_S: { - HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[2]]); + HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod, ip[2]); void* helperArg = LOCAL_VAR(ip[3], void*); LOCAL_VAR(ip[1], void*) = helperFtn(helperArg); @@ -1715,7 +1724,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_PS: { - HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); void* helperArg = pMethod->pDataItems[ip[4]]; LOCAL_VAR(ip[1], void*) = helperFtn(helperArg, LOCAL_VAR(ip[2], void*)); @@ -1725,7 +1734,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_SP: { - HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); void* helperArg = pMethod->pDataItems[ip[4]]; LOCAL_VAR(ip[1], void*) = helperFtn(LOCAL_VAR(ip[2], void*), helperArg); @@ -1738,7 +1747,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[4]]; void* helperArg = DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_P_P helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); LOCAL_VAR(ip[1], void*) = helperFtn(helperArg); ip += 5; @@ -1750,7 +1759,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; void* helperArg = DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[4]); LOCAL_VAR(ip[1], void*) = helperFtn(helperArg, LOCAL_VAR(ip[3], void*)); ip += 6; @@ -1762,7 +1771,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; void* helperArg = DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[4]); LOCAL_VAR(ip[1], void*) = helperFtn(helperArg, LOCAL_VAR_ADDR(ip[3], void*)); ip += 6; break; @@ -1770,7 +1779,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_P_PA: { - HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_P_PP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); void* helperArg = pMethod->pDataItems[ip[4]]; LOCAL_VAR(ip[1], void*) = helperFtn(helperArg, LOCAL_VAR_ADDR(ip[2], void*)); ip += 5; @@ -1782,7 +1791,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; void* helperArg = DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_V_PPP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_V_PPP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[4]); helperFtn(LOCAL_VAR_ADDR(ip[1], void*), helperArg, LOCAL_VAR(ip[3], void*)); ip += 6; break; @@ -1790,7 +1799,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr case INTOP_CALL_HELPER_V_APS: { - HELPER_FTN_V_PPP helperFtn = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_V_PPP helperFtn = GetPossiblyIndirectHelper(pMethod, ip[3]); void* helperArg = pMethod->pDataItems[ip[4]]; helperFtn(LOCAL_VAR_ADDR(ip[1], void*), helperArg, LOCAL_VAR(ip[2], void*)); ip += 5; @@ -1986,9 +1995,6 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr int32_t vtSize = ip[4]; void *vtThis = stack + returnOffset; - // clear the valuetype - memset(vtThis, 0, vtSize); - // pass the address of the valuetype LOCAL_VAR(callArgsOffset, void*) = vtThis; @@ -2021,18 +2027,6 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr ip += 3; break; } - case INTOP_GC_COLLECT: - { - // HACK: blocking gc of all generations to enable early stackwalk testing - // Interpreter-TODO: Remove this - { - pInterpreterFrame->SetTopInterpMethodContextFrame(pFrame); - GCX_COOP(); - GCHeapUtilities::GetGCHeap()->GarbageCollect(-1, false, collection_blocking | collection_aggressive); - } - ip++; - break; - } case INTOP_THROW: { OBJECTREF throwable; @@ -2068,7 +2062,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr int opcode = *ip; int dreg = ip[1]; int sreg = ip[2]; - HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[3]]); + HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper(pMethod, ip[3]); MethodTable *pMT = (MethodTable*)pMethod->pDataItems[ip[4]]; // private static ref byte Unbox(MethodTable* toTypeHnd, object obj) @@ -2088,7 +2082,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; MethodTable *pMTBoxedObj = (MethodTable*)DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_BOX_UNBOX helper = GetPossiblyIndirectHelper(pMethod, ip[4]); // private static ref byte Unbox(MethodTable* toTypeHnd, object obj) Object *src = LOCAL_VAR(sreg, Object*); @@ -2105,7 +2099,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr COMPlusThrow(kArgumentOutOfRangeException); MethodTable* arrayClsHnd = (MethodTable*)pMethod->pDataItems[ip[3]]; - HELPER_FTN_NEWARR helper = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_NEWARR helper = GetPossiblyIndirectHelper(pMethod, ip[4]); Object* arr = helper(arrayClsHnd, (intptr_t)length); LOCAL_VAR(ip[1], OBJECTREF) = ObjectToOBJECTREF(arr); @@ -2122,7 +2116,7 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr InterpGenericLookup *pLookup = (InterpGenericLookup*)&pMethod->pDataItems[ip[5]]; MethodTable *arrayClsHnd = (MethodTable*)DoGenericLookup(LOCAL_VAR(ip[2], void*), pLookup); - HELPER_FTN_NEWARR helper = GetPossiblyIndirectHelper(pMethod->pDataItems[ip[4]]); + HELPER_FTN_NEWARR helper = GetPossiblyIndirectHelper(pMethod, ip[4]); Object* arr = helper(arrayClsHnd, (intptr_t)length); LOCAL_VAR(ip[1], OBJECTREF) = ObjectToOBJECTREF(arr); @@ -2460,11 +2454,8 @@ do \ case INTOP_THROW_PNSE: COMPlusThrow(kPlatformNotSupportedException); break; - case INTOP_FAILFAST: - assert(0); - break; default: - assert(0); + assert(!"Unimplemented or invalid interpreter opcode"); break; } } diff --git a/src/runtime/src/coreclr/vm/jitinterface.cpp b/src/runtime/src/coreclr/vm/jitinterface.cpp index b0e80d386f8..c1bd8aad1fc 100644 --- a/src/runtime/src/coreclr/vm/jitinterface.cpp +++ b/src/runtime/src/coreclr/vm/jitinterface.cpp @@ -12355,41 +12355,6 @@ CORINFO_CLASS_HANDLE CEECodeGenInfo::getStaticFieldCurrentClass(CORINFO_FIELD_HA return result; } -/*********************************************************************/ -static void *GetClassSync(MethodTable *pMT) -{ - STANDARD_VM_CONTRACT; - - GCX_COOP(); - - OBJECTREF ref = pMT->GetManagedClassObject(); - return (void*)ref->GetSyncBlock()->GetMonitor(); -} - -/*********************************************************************/ -void* CEECodeGenInfo::getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, - void **ppIndirection) -{ - CONTRACTL { - THROWS; - GC_TRIGGERS; - MODE_PREEMPTIVE; - } CONTRACTL_END; - - void * result = NULL; - - if (ppIndirection != NULL) - *ppIndirection = NULL; - - JIT_TO_EE_TRANSITION(); - - result = GetClassSync((GetMethod(ftnHnd))->GetMethodTable()); - - EE_TO_JIT_TRANSITION(); - - return result; -} - CORINFO_METHOD_INFO* CEECodeGenInfo::getMethodInfoInternal() { LIMITED_METHOD_CONTRACT; @@ -14850,13 +14815,6 @@ CORINFO_CLASS_HANDLE CEEInfo::getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE fi UNREACHABLE(); // only called on derived class. } -void* CEEInfo::getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, - void **ppIndirection) -{ - LIMITED_METHOD_CONTRACT; - UNREACHABLE(); // only called on derived class. -} - HRESULT CEEInfo::allocPgoInstrumentationBySchema( CORINFO_METHOD_HANDLE ftnHnd, /* IN */ PgoInstrumentationSchema* pSchema, /* IN/OUT */ diff --git a/src/runtime/src/coreclr/vm/jitinterface.h b/src/runtime/src/coreclr/vm/jitinterface.h index 00ed950e5d5..e825d94a129 100644 --- a/src/runtime/src/coreclr/vm/jitinterface.h +++ b/src/runtime/src/coreclr/vm/jitinterface.h @@ -574,7 +574,6 @@ class CEECodeGenInfo : public CEEInfo InfoAccessType constructStringLiteral(CORINFO_MODULE_HANDLE scopeHnd, mdToken metaTok, void **ppValue) override; InfoAccessType emptyStringLiteral(void ** ppValue) override; CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool* pIsSpeculative) override; - void* getMethodSync(CORINFO_METHOD_HANDLE ftnHnd, void **ppIndirection) override; CORINFO_METHOD_INFO* getMethodInfoInternal(); CORJIT_FLAGS* getJitFlagsInternal(); diff --git a/src/runtime/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs b/src/runtime/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs index 9abf075d60c..d24a7314592 100644 --- a/src/runtime/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs +++ b/src/runtime/src/libraries/Common/src/Interop/OSX/System.Security.Cryptography.Native.Apple/Interop.Ssl.cs @@ -16,8 +16,6 @@ internal static partial class Interop { internal static partial class AppleCrypto { - private static readonly IdnMapping s_idnMapping = new IdnMapping(); - // Read data from connection (or an instance delegate captured context) and write it to data // dataLength comes in as the capacity of data, goes out as bytes written. // Note: the true type of dataLength is `size_t*`, but on macOS that's most equal to `void**` @@ -152,13 +150,6 @@ internal static unsafe partial int SslSetIoCallbacks( [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_SslRead")] internal static unsafe partial PAL_TlsIo SslRead(SafeSslHandle sslHandle, byte* writeFrom, int count, out int bytesWritten); - [LibraryImport(Interop.Libraries.AppleCryptoNative)] - private static partial int AppleCryptoNative_SslIsHostnameMatch( - SafeSslHandle handle, - SafeCreateHandle cfHostname, - SafeCFDateHandle cfValidTime, - out int pOSStatus); - [LibraryImport(Interop.Libraries.AppleCryptoNative, EntryPoint = "AppleCryptoNative_SslShutdown")] internal static partial int SslShutdown(SafeSslHandle sslHandle); @@ -462,40 +453,6 @@ internal static unsafe int SslCtxSetAlpnProtocol(SafeSslHandle ctx, SslApplicati protocol.Dispose(); } } - - public static bool SslCheckHostnameMatch(SafeSslHandle handle, string hostName, DateTime notBefore, out int osStatus) - { - int result; - // The IdnMapping converts Unicode input into the IDNA punycode sequence. - // It also does host case normalization. The bypass logic would be something - // like "all characters being within [a-z0-9.-]+" - // - // The SSL Policy (SecPolicyCreateSSL) has been verified as not inherently supporting - // IDNA as of macOS 10.12.1 (Sierra). If it supports low-level IDNA at a later date, - // this code could be removed. - // - // It was verified as supporting case invariant match as of 10.12.1 (Sierra). - string matchName = string.IsNullOrEmpty(hostName) ? string.Empty : s_idnMapping.GetAscii(hostName); - - using (SafeCFDateHandle cfNotBefore = CoreFoundation.CFDateCreate(notBefore)) - using (SafeCreateHandle cfHostname = CoreFoundation.CFStringCreateWithCString(matchName)) - { - result = AppleCryptoNative_SslIsHostnameMatch(handle, cfHostname, cfNotBefore, out osStatus); - } - - switch (result) - { - case 0: - return false; - case 1: - return true; - default: - if (NetEventSource.Log.IsEnabled()) - NetEventSource.Error(null, $"AppleCryptoNative_SslIsHostnameMatch returned '{result}' for '{hostName}'"); - Debug.Fail($"AppleCryptoNative_SslIsHostnameMatch returned {result}"); - throw new SslException(); - } - } } } diff --git a/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs b/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs index 0f69af42cb0..376a133244b 100644 --- a/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs +++ b/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptSignHash.cs @@ -111,5 +111,44 @@ internal static unsafe void BCryptSignHashPqcPure( throw Interop.BCrypt.CreateCryptographicException(status); } } + + internal static unsafe void BCryptSignHashPqcPreHash( + SafeBCryptKeyHandle key, + ReadOnlySpan hash, + string hashAlgorithmIdentifier, + ReadOnlySpan context, + Span destination) + { + NTSTATUS status; + int bytesWritten; + + fixed (byte* pHash = &MemoryMarshal.GetReference(hash)) + fixed (byte* pDest = &MemoryMarshal.GetReference(destination)) + fixed (byte* pContext = &MemoryMarshal.GetReference(context)) + fixed (char* pHashAlgorithmIdentifier = hashAlgorithmIdentifier) + { + BCRYPT_PQDSA_PADDING_INFO paddingInfo = default; + paddingInfo.pbCtx = (IntPtr)pContext; + paddingInfo.cbCtx = context.Length; + paddingInfo.pszPreHashAlgId = (IntPtr)pHashAlgorithmIdentifier; + + status = BCryptSignHash( + key, + &paddingInfo, + pHash, + hash.Length, + pDest, + destination.Length, + out bytesWritten, + BCryptSignVerifyFlags.BCRYPT_PAD_PQDSA); + } + + Debug.Assert(bytesWritten == destination.Length); + + if (status != BCrypt.NTSTATUS.STATUS_SUCCESS) + { + throw BCrypt.CreateCryptographicException(status); + } + } } } diff --git a/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs b/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs index 6934e7e2c11..da39ca0dcdd 100644 --- a/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs +++ b/src/runtime/src/libraries/Common/src/Interop/Windows/BCrypt/Interop.BCryptVerifySignature.cs @@ -115,5 +115,37 @@ internal static unsafe bool BCryptVerifySignaturePqcPure( return status == NTSTATUS.STATUS_SUCCESS; } + + internal static unsafe bool BCryptVerifySignaturePqcPreHash( + SafeBCryptKeyHandle key, + ReadOnlySpan hash, + string hashAlgorithmIdentifier, + ReadOnlySpan context, + ReadOnlySpan signature) + { + NTSTATUS status; + + fixed (byte* pHash = &MemoryMarshal.GetReference(hash)) + fixed (byte* pSignature = &MemoryMarshal.GetReference(signature)) + fixed (byte* pContext = &MemoryMarshal.GetReference(context)) + fixed (char* pHashAlgorithmIdentifier = hashAlgorithmIdentifier) + { + BCRYPT_PQDSA_PADDING_INFO paddingInfo = default; + paddingInfo.pbCtx = (IntPtr)pContext; + paddingInfo.cbCtx = context.Length; + paddingInfo.pszPreHashAlgId = (IntPtr)pHashAlgorithmIdentifier; + + status = BCryptVerifySignature( + key, + &paddingInfo, + pHash, + hash.Length, + pSignature, + signature.Length, + BCryptSignVerifyFlags.BCRYPT_PAD_PQDSA); + } + + return status == NTSTATUS.STATUS_SUCCESS; + } } } diff --git a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs index 12ca0f66a8b..1c9a498a273 100644 --- a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs +++ b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs @@ -325,7 +325,29 @@ public void SignPreHash(ReadOnlySpan hash, Span destination, string SR.Argument_SignatureContextTooLong255); } - Helpers.ValidateHashLength(hash, hashAlgorithmOid); + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + if (hashAlgorithmIdentifier is null) + { + throw new CryptographicException(SR.Format(SR.Cryptography_UnknownHashAlgorithm, hashAlgorithmOid)); + } + + if (insufficientCollisionResistance) + { + throw new CryptographicException(SR.Format( + SR.Cryptography_HashMLDsaAlgorithmMismatch, + Algorithm.Name, + hashAlgorithmIdentifier)); + } + + if (hashLengthInBytes != hash.Length) + { + throw new CryptographicException(SR.Cryptography_HashLengthMismatch); + } + ThrowIfDisposed(); SignPreHashCore(hash, context, hashAlgorithmOid, destination); @@ -413,14 +435,24 @@ public bool VerifyPreHash(ReadOnlySpan hash, ReadOnlySpan signature, SR.Argument_SignatureContextTooLong255); } - Helpers.ValidateHashLength(hash, hashAlgorithmOid); - ThrowIfDisposed(); + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); - if (signature.Length != Algorithm.SignatureSizeInBytes) + if (hashAlgorithmIdentifier is null || insufficientCollisionResistance || + signature.Length != Algorithm.SignatureSizeInBytes) { return false; } + if (hashLengthInBytes != hash.Length) + { + throw new CryptographicException(SR.Cryptography_HashLengthMismatch); + } + + ThrowIfDisposed(); + return VerifyPreHashCore(hash, context, hashAlgorithmOid, signature); } @@ -2114,7 +2146,76 @@ internal static void ThrowIfNotSupported() } } + // Returns a hash algorithm identifier for an OID. + // insufficientCollisionResistance is true if the hash algorithm is known, but does not meet the required + // collision resistance from FIPS 204. + private protected string? MapHashOidToAlgorithm( + string hashOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance) + { + int hashLambda; + string hashAlgorithmIdentifier; + + switch (hashOid) + { + case Oids.Md5: + hashLengthInBytes = 128 / 8; + insufficientCollisionResistance = true; + return HashAlgorithmNames.MD5; + case Oids.Sha1: + hashLengthInBytes = 160 / 8; + insufficientCollisionResistance = true; + return HashAlgorithmNames.SHA1; + case Oids.Sha256: + hashLengthInBytes = 256 / 8; + hashLambda = 256 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA256; + break; + case Oids.Sha3_256: + hashLengthInBytes = 256 / 8; + hashLambda = 256 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA3_256; + break; + case Oids.Sha384: + hashLengthInBytes = 384 / 8; + hashLambda = 384 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA384; + break; + case Oids.Sha3_384: + hashLengthInBytes = 384 / 8; + hashLambda = 384 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA3_384; + break; + case Oids.Sha512: + hashLengthInBytes = 512 / 8; + hashLambda = 512 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA512; + break; + case Oids.Sha3_512: + hashLengthInBytes = 512 / 8; + hashLambda = 512 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHA3_512; + break; + case Oids.Shake128: // SHAKE-128 with 256-bits of output + hashLengthInBytes = 256 / 8; + hashLambda = 256 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHAKE128; + break; + case Oids.Shake256: // SHAKE-256 with 512-bits of output + hashLengthInBytes = 512 / 8; + hashLambda = 512 / 2; + hashAlgorithmIdentifier = HashAlgorithmNames.SHAKE256; + break; + default: + hashLengthInBytes = 0; + insufficientCollisionResistance = false; + return null; + } + insufficientCollisionResistance = hashLambda < Algorithm.LambdaCollisionStrength; + return hashAlgorithmIdentifier; + } private delegate TResult ExportPkcs8PrivateKeyFunc(ReadOnlySpan pkcs8); } diff --git a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs index c058daab3bb..63d29d3dae6 100644 --- a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs +++ b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaAlgorithm.cs @@ -54,31 +54,21 @@ public sealed class MLDsaAlgorithm : IEquatable public int SignatureSizeInBytes { get; } internal string Oid { get; } - - /// - /// Initializes a new instance of the structure with a custom name. - /// - /// - /// The name of the algorithm. - /// - /// - /// The size of the secret key in bytes. - /// - /// - /// The size of the public key in bytes. - /// - /// - /// The size of the signature in bytes. - /// - /// - /// The OID of the algorithm. - /// - private MLDsaAlgorithm(string name, int secretKeySizeInBytes, int publicKeySizeInBytes, int signatureSizeInBytes, string oid) + internal int LambdaCollisionStrength { get; } + + private MLDsaAlgorithm( + string name, + int secretKeySizeInBytes, + int publicKeySizeInBytes, + int signatureSizeInBytes, + int lambdaCollisionStrength, + string oid) { Name = name; SecretKeySizeInBytes = secretKeySizeInBytes; PublicKeySizeInBytes = publicKeySizeInBytes; SignatureSizeInBytes = signatureSizeInBytes; + LambdaCollisionStrength = lambdaCollisionStrength; Oid = oid; } @@ -91,7 +81,7 @@ private MLDsaAlgorithm(string name, int secretKeySizeInBytes, int publicKeySizeI /// /// An ML-DSA algorithm identifier for the ML-DSA-44 algorithm. /// - public static MLDsaAlgorithm MLDsa44 { get; } = new MLDsaAlgorithm("ML-DSA-44", 2560, 1312, 2420, Oids.MLDsa44); + public static MLDsaAlgorithm MLDsa44 { get; } = new MLDsaAlgorithm("ML-DSA-44", 2560, 1312, 2420, 128, Oids.MLDsa44); /// /// Gets an ML-DSA algorithm identifier for the ML-DSA-65 algorithm. @@ -99,7 +89,7 @@ private MLDsaAlgorithm(string name, int secretKeySizeInBytes, int publicKeySizeI /// /// An ML-DSA algorithm identifier for the ML-DSA-65 algorithm. /// - public static MLDsaAlgorithm MLDsa65 { get; } = new MLDsaAlgorithm("ML-DSA-65", 4032, 1952, 3309, Oids.MLDsa65); + public static MLDsaAlgorithm MLDsa65 { get; } = new MLDsaAlgorithm("ML-DSA-65", 4032, 1952, 3309, 192, Oids.MLDsa65); /// /// Gets an ML-DSA algorithm identifier for the ML-DSA-87 algorithm. @@ -107,7 +97,7 @@ private MLDsaAlgorithm(string name, int secretKeySizeInBytes, int publicKeySizeI /// /// An ML-DSA algorithm identifier for the ML-DSA-87 algorithm. /// - public static MLDsaAlgorithm MLDsa87 { get; } = new MLDsaAlgorithm("ML-DSA-87", 4896, 2592, 4627, Oids.MLDsa87); + public static MLDsaAlgorithm MLDsa87 { get; } = new MLDsaAlgorithm("ML-DSA-87", 4896, 2592, 4627, 256, Oids.MLDsa87); internal static MLDsaAlgorithm? GetMLDsaAlgorithmFromOid(string? oid) { diff --git a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs index 63825cb3481..bd384cab56c 100644 --- a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs +++ b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaCng.Windows.cs @@ -267,12 +267,74 @@ protected override unsafe bool VerifyDataCore(ReadOnlySpan data, ReadOnlyS } /// - protected override void SignPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => - throw new PlatformNotSupportedException(); + protected override unsafe void SignPreHashCore( + ReadOnlySpan hash, + ReadOnlySpan context, + string hashAlgorithmOid, + Span destination) + { + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + Debug.Assert(hashAlgorithmIdentifier is not null); + Debug.Assert(!insufficientCollisionResistance); + Debug.Assert(hashLengthInBytes == hash.Length); + + using (SafeNCryptKeyHandle duplicatedHandle = _key.Handle) + { + fixed (char* pHashAlgorithmIdentifier = hashAlgorithmIdentifier) + fixed (void* pContext = context) + { + BCRYPT_PQDSA_PADDING_INFO paddingInfo = default; + paddingInfo.pbCtx = (IntPtr)pContext; + paddingInfo.cbCtx = context.Length; + paddingInfo.pszPreHashAlgId = (IntPtr)pHashAlgorithmIdentifier; + + duplicatedHandle.SignHash( + hash, + destination, + Interop.NCrypt.AsymmetricPaddingMode.NCRYPT_PAD_PQDSA_FLAG, + &paddingInfo); + } + } + } /// - protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => - throw new PlatformNotSupportedException(); + protected override unsafe bool VerifyPreHashCore( + ReadOnlySpan hash, + ReadOnlySpan context, + string hashAlgorithmOid, + ReadOnlySpan signature) + { + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + Debug.Assert(hashAlgorithmIdentifier is not null); + Debug.Assert(!insufficientCollisionResistance); + Debug.Assert(hashLengthInBytes == hash.Length); + + using (SafeNCryptKeyHandle duplicatedHandle = _key.Handle) + { + fixed (char* pHashAlgorithmIdentifier = hashAlgorithmIdentifier) + fixed (void* pContext = context) + { + BCRYPT_PQDSA_PADDING_INFO paddingInfo = default; + paddingInfo.pbCtx = (IntPtr)pContext; + paddingInfo.cbCtx = context.Length; + paddingInfo.pszPreHashAlgId = (IntPtr)pHashAlgorithmIdentifier; + + return duplicatedHandle.VerifyHash( + hash, + signature, + Interop.NCrypt.AsymmetricPaddingMode.NCRYPT_PAD_PQDSA_FLAG, + &paddingInfo); + } + } + } [SupportedOSPlatform("windows")] internal static MLDsaCng ImportPkcs8PrivateKey(byte[] source, out int bytesRead) diff --git a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs index 65c3c320960..5b62f4a6e40 100644 --- a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs +++ b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/MLDsaImplementation.Windows.cs @@ -47,11 +47,46 @@ protected override void SignDataCore(ReadOnlySpan data, ReadOnlySpan protected override bool VerifyDataCore(ReadOnlySpan data, ReadOnlySpan context, ReadOnlySpan signature) => Interop.BCrypt.BCryptVerifySignaturePqcPure(_key, data, context, signature); - protected override void SignPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, Span destination) => - throw new PlatformNotSupportedException(); + protected override void SignPreHashCore( + ReadOnlySpan hash, + ReadOnlySpan context, + string hashAlgorithmOid, + Span destination) + { + if (!_hasSecretKey) + { + throw new CryptographicException(SR.Cryptography_MLDsaNoSecretKey); + } + + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + Debug.Assert(hashAlgorithmIdentifier is not null); + Debug.Assert(!insufficientCollisionResistance); + Debug.Assert(hashLengthInBytes == hash.Length); - protected override bool VerifyPreHashCore(ReadOnlySpan hash, ReadOnlySpan context, string hashAlgorithmOid, ReadOnlySpan signature) => - throw new PlatformNotSupportedException(); + Interop.BCrypt.BCryptSignHashPqcPreHash(_key, hash, hashAlgorithmIdentifier, context, destination); + } + + protected override bool VerifyPreHashCore( + ReadOnlySpan hash, + ReadOnlySpan context, + string hashAlgorithmOid, + ReadOnlySpan signature) + { + string? hashAlgorithmIdentifier = MapHashOidToAlgorithm( + hashAlgorithmOid, + out int hashLengthInBytes, + out bool insufficientCollisionResistance); + + Debug.Assert(hashAlgorithmIdentifier is not null); + Debug.Assert(!insufficientCollisionResistance); + Debug.Assert(hashLengthInBytes == hash.Length); + + return Interop.BCrypt.BCryptVerifySignaturePqcPreHash(_key, hash, hashAlgorithmIdentifier, context, signature); + } internal static partial MLDsaImplementation GenerateKeyImpl(MLDsaAlgorithm algorithm) { diff --git a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs index 678e8ea6d78..c9c0a6a6f77 100644 --- a/src/runtime/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs +++ b/src/runtime/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/Pkcs12LoaderLimits.cs @@ -372,7 +372,12 @@ public bool IgnoreEncryptedAuthSafes /// to fail loading when duplicate attributes are found. /// The default is . /// - internal bool AllowDuplicateAttributes +#if NET10_0_OR_GREATER + public +#else + internal +#endif + bool AllowDuplicateAttributes { get => _allowDuplicateAttributes; set diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs index 552d77c21e8..0d63c336370 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestImplementation.cs @@ -99,7 +99,9 @@ internal static MLDsaTestImplementation CreateOverriddenCoreMethodsFail(MLDsaAlg ExportMLDsaPublicKeyHook = _ => Assert.Fail(), ExportMLDsaSecretKeyHook = _ => Assert.Fail(), SignDataHook = (_, _, _) => Assert.Fail(), + SignPreHashHook = delegate { Assert.Fail(); }, VerifyDataHook = (_, _, _) => { Assert.Fail(); return false; }, + VerifyPreHashHook = delegate { Assert.Fail(); return false; }, DisposeHook = _ => { }, TryExportPkcs8PrivateKeyHook = (_, out bytesWritten) => diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs index b6cb0c35672..27b920761db 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTests.cs @@ -128,8 +128,8 @@ public static void ArgumentValidation(MLDsaAlgorithm algorithm, bool shouldDispo AssertExtensions.Throws("destination", () => mldsa.ExportMLDsaPrivateSeed(new byte[privateSeedSize + 1])); AssertExtensions.Throws("destination", () => mldsa.SignData(ReadOnlySpan.Empty, new byte[signatureSize - 1], ReadOnlySpan.Empty)); AssertExtensions.Throws("destination", () => mldsa.SignData(ReadOnlySpan.Empty, new byte[signatureSize + 1], ReadOnlySpan.Empty)); - AssertExtensions.Throws("destination", () => mldsa.SignPreHash(new byte[HashInfo.Sha256.OutputSize], new byte[signatureSize - 1], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); - AssertExtensions.Throws("destination", () => mldsa.SignPreHash(new byte[HashInfo.Sha256.OutputSize], new byte[signatureSize + 1], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws("destination", () => mldsa.SignPreHash(new byte[HashInfo.Sha512.OutputSize], new byte[signatureSize - 1], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws("destination", () => mldsa.SignPreHash(new byte[HashInfo.Sha512.OutputSize], new byte[signatureSize + 1], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); // Context length must be less than 256 AssertExtensions.Throws("context", () => mldsa.SignData(ReadOnlySpan.Empty, signature, new byte[256])); @@ -140,21 +140,17 @@ public static void ArgumentValidation(MLDsaAlgorithm algorithm, bool shouldDispo AssertExtensions.Throws("context", () => mldsa.SignPreHash(hash, HashInfo.Sha256.Oid, new byte[256])); // Hash length of known OID hash algorithms must be correct - AssertExtensions.Throws(() => mldsa.SignPreHash(new byte[HashInfo.Sha256.OutputSize - 1], new byte[signatureSize], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); - AssertExtensions.Throws(() => mldsa.SignPreHash(new byte[HashInfo.Sha256.OutputSize + 1], new byte[signatureSize], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); - AssertExtensions.Throws(() => mldsa.VerifyPreHash(new byte[HashInfo.Sha256.OutputSize - 1], new byte[signatureSize], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); - AssertExtensions.Throws(() => mldsa.VerifyPreHash(new byte[HashInfo.Sha256.OutputSize + 1], new byte[signatureSize], HashInfo.Sha256.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws(() => mldsa.SignPreHash(new byte[HashInfo.Sha512.OutputSize - 1], new byte[signatureSize], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws(() => mldsa.SignPreHash(new byte[HashInfo.Sha512.OutputSize + 1], new byte[signatureSize], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws(() => mldsa.VerifyPreHash(new byte[HashInfo.Sha512.OutputSize - 1], new byte[signatureSize], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); + AssertExtensions.Throws(() => mldsa.VerifyPreHash(new byte[HashInfo.Sha512.OutputSize + 1], new byte[signatureSize], HashInfo.Sha512.Oid, ReadOnlySpan.Empty)); // Must be valid OID Assert.Throws(() => mldsa.SignPreHash([], "not.an.oid")); Assert.Throws(() => mldsa.SignPreHash([], signature, "not-an-oid")); - Assert.Throws(() => mldsa.VerifyPreHash(Array.Empty(), signature, "1")); - Assert.Throws(() => mldsa.VerifyPreHash([], signature.AsSpan(), "a")); Assert.Throws(() => mldsa.SignPreHash([1], string.Empty)); Assert.Throws(() => mldsa.SignPreHash([1], signature, "-1.0.0")); - Assert.Throws(() => mldsa.VerifyPreHash(new byte[] { 1 }, signature, "a")); - Assert.Throws(() => mldsa.VerifyPreHash([1], signature.AsSpan(), "a")); } public static IEnumerable ArgumentValidation_Hash_WrongSizeInputs() @@ -194,61 +190,26 @@ public static void ArgumentValidation_Hash_WrongSize(bool shouldDispose, HashInf } [Fact] - public static void ArgumentValidation_HashAlgorithm_UnknownOidCallsCore() + public static void ArgumentValidation_HashAlgorithm_UnknownOidDoesNotCallCore() { - using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateNoOp(MLDsaAlgorithm.MLDsa44); + using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateOverriddenCoreMethodsFail(MLDsaAlgorithm.MLDsa44); byte[] signature = new byte[MLDsaAlgorithm.MLDsa44.SignatureSizeInBytes]; string hashAlgorithmOid = "1.0"; - - mlDsa.SignPreHashHook = (_, _, _, _) => { }; - mlDsa.AddSignatureBufferIsSameAssertion(signature.AsMemory()); - mlDsa.AddHashAlgorithmIsSameAssertion(hashAlgorithmOid.AsMemory()); - - _ = mlDsa.SignPreHash([], hashAlgorithmOid); - Assert.Equal(1, mlDsa.SignPreHashCoreCallCount); - - mlDsa.SignPreHash([], signature, hashAlgorithmOid); - Assert.Equal(2, mlDsa.SignPreHashCoreCallCount); - - _ = mlDsa.SignPreHash([1], hashAlgorithmOid); - Assert.Equal(3, mlDsa.SignPreHashCoreCallCount); - - mlDsa.SignPreHash([1], signature, hashAlgorithmOid); - Assert.Equal(4, mlDsa.SignPreHashCoreCallCount); - - mlDsa.SignPreHashHook = (_, _, _, _) => Assert.Fail(); - mlDsa.VerifyPreHashHook = (_, _, _, _) => true; - mlDsa.AddSignatureBufferIsSameAssertion(signature.AsMemory()); - mlDsa.AddHashAlgorithmIsSameAssertion(hashAlgorithmOid.AsMemory()); - - _ = mlDsa.VerifyPreHash(Array.Empty(), signature, hashAlgorithmOid); - Assert.Equal(1, mlDsa.VerifyPreHashCoreCallCount); - - _ = mlDsa.VerifyPreHash([], signature.AsSpan(), hashAlgorithmOid); - Assert.Equal(2, mlDsa.VerifyPreHashCoreCallCount); - - _ = mlDsa.VerifyPreHash(new byte[] { 1 }, signature, hashAlgorithmOid); - Assert.Equal(3, mlDsa.VerifyPreHashCoreCallCount); - - _ = mlDsa.VerifyPreHash([1], signature.AsSpan(), hashAlgorithmOid); - Assert.Equal(4, mlDsa.VerifyPreHashCoreCallCount); + CryptographicException ce = Assert.Throws(() => mlDsa.SignPreHash([], hashAlgorithmOid)); + Assert.Contains(hashAlgorithmOid, ce.Message); } - public static IEnumerable AllHashesAndLengthsAndExtraUnknown() + public static IEnumerable AllHashesAndLengths() { foreach (HashInfo hashInfo in HashInfo.AllHashInfos()) { yield return new object[] { hashInfo.Oid, hashInfo.OutputSize }; } - - yield return new object[] { "1.0", 0 }; - yield return new object[] { "1.0", 1 }; - yield return new object[] { "1.0", 2 }; } [Theory] - [MemberData(nameof(AllHashesAndLengthsAndExtraUnknown))] + [MemberData(nameof(AllHashesAndLengths))] public static void SignPreHash_CallsCore(string hashAlgorithmOid, int hashLength) { MLDsaAlgorithm algorithm = MLDsaAlgorithm.MLDsa44; @@ -285,7 +246,7 @@ public static void SignPreHash_CallsCore(string hashAlgorithmOid, int hashLength } [Theory] - [MemberData(nameof(AllHashesAndLengthsAndExtraUnknown))] + [MemberData(nameof(AllHashesAndLengths))] public static void VerifyPreHash_CallsCore(string hashAlgorithmOid, int hashLength) { using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateNoOp(MLDsaAlgorithm.MLDsa44); @@ -321,7 +282,7 @@ public static void VerifyPreHash_CallsCore(string hashAlgorithmOid, int hashLeng } [Theory] - [MemberData(nameof(AllHashesAndLengthsAndExtraUnknown))] + [MemberData(nameof(AllHashesAndLengths))] public static void VerifyPreHash_ByteArray_CallsCore(string hashAlgorithmOid, int hashLength) { using MLDsaTestImplementation mlDsa = MLDsaTestImplementation.CreateNoOp(MLDsaAlgorithm.MLDsa44); diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs index c2da6357672..6f4ed26dc51 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsBase.cs @@ -29,7 +29,7 @@ public void AlgorithmIsAssigned(MLDsaAlgorithm algorithm) public void GenerateSignVerifyNoContext(MLDsaAlgorithm algorithm) { using MLDsa mldsa = GenerateKey(algorithm); - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature = mldsa.SignData(data); ExerciseSuccessfulVerify(mldsa, data, signature, []); } @@ -40,9 +40,9 @@ public void GenerateSignVerifyPreHashNoContext(MLDsaAlgorithm algorithm) { using MLDsa mldsa = GenerateKey(algorithm); byte[] data = [1, 2, 3, 4, 5]; - byte[] hash = HashInfo.Sha256.GetHash(data); - byte[] signature = mldsa.SignPreHash(hash, HashInfo.Sha256.Oid, []); - ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha256.Oid, hash, signature, []); + byte[] hash = HashInfo.Sha512.GetHash(data); + byte[] signature = mldsa.SignPreHash(hash, HashInfo.Sha512.Oid, []); + ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha512.Oid, hash, signature, []); } [Theory] @@ -50,8 +50,8 @@ public void GenerateSignVerifyPreHashNoContext(MLDsaAlgorithm algorithm) public void GenerateSignVerifyWithContext(MLDsaAlgorithm algorithm) { using MLDsa mldsa = GenerateKey(algorithm); - byte[] context = [ 1, 1, 3, 5, 6 ]; - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] context = [1, 1, 3, 5, 6]; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature = mldsa.SignData(data, context); ExerciseSuccessfulVerify(mldsa, data, signature, context); @@ -64,10 +64,10 @@ public void GenerateSignVerifyPreHashWithContext(MLDsaAlgorithm algorithm) using MLDsa mldsa = GenerateKey(algorithm); byte[] context = [1, 1, 3, 5, 6]; byte[] data = [1, 2, 3, 4, 5]; - byte[] hash = HashInfo.Sha256.GetHash(data); - byte[] signature = mldsa.SignPreHash(hash, HashInfo.Sha256.Oid, context); + byte[] hash = HashInfo.Sha512.GetHash(data); + byte[] signature = mldsa.SignPreHash(hash, HashInfo.Sha512.Oid, context); - ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha256.Oid, hash, signature, context); + ExerciseSuccessfulVerifyPreHash(mldsa, HashInfo.Sha512.Oid, hash, signature, context); } [ConditionalTheory(typeof(MLDsaTestHelpers), nameof(MLDsaTestHelpers.SigningEmptyDataIsSupported))] @@ -96,9 +96,9 @@ public void GenerateSignVerifyEmptyMessageWithContext(MLDsaAlgorithm algorithm) public void GenerateSignExportPublicVerifyWithPublicOnly(MLDsaAlgorithm algorithm) { byte[] publicKey; - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature; - byte[] hash = HashInfo.Sha256.GetHash(data); + byte[] hash = HashInfo.Sha512.GetHash(data); byte[] signaturePreHash; using (MLDsa mldsa = GenerateKey(algorithm)) @@ -106,8 +106,8 @@ public void GenerateSignExportPublicVerifyWithPublicOnly(MLDsaAlgorithm algorith signature = mldsa.SignData(data); AssertExtensions.TrueExpression(mldsa.VerifyData(data, signature)); - signaturePreHash = mldsa.SignPreHash(hash, HashInfo.Sha256.Oid); - AssertExtensions.TrueExpression(mldsa.VerifyPreHash(hash, signaturePreHash, HashInfo.Sha256.Oid)); + signaturePreHash = mldsa.SignPreHash(hash, HashInfo.Sha512.Oid); + AssertExtensions.TrueExpression(mldsa.VerifyPreHash(hash, signaturePreHash, HashInfo.Sha512.Oid)); publicKey = mldsa.ExportMLDsaPublicKey(); } @@ -115,8 +115,8 @@ public void GenerateSignExportPublicVerifyWithPublicOnly(MLDsaAlgorithm algorith using (MLDsa mldsaPub = ImportPublicKey(algorithm, publicKey)) { ExerciseSuccessfulVerify(mldsaPub, data, signature, []); - ExerciseSuccessfulVerifyPreHash(mldsaPub, HashInfo.Sha256.Oid, hash, signaturePreHash, []); - AssertExtensions.FalseExpression(mldsaPub.VerifyPreHash(hash, signature, HashInfo.Sha256.Oid)); + ExerciseSuccessfulVerifyPreHash(mldsaPub, HashInfo.Sha512.Oid, hash, signaturePreHash, []); + AssertExtensions.FalseExpression(mldsaPub.VerifyPreHash(hash, signature, HashInfo.Sha512.Oid)); } } @@ -125,7 +125,7 @@ public void GenerateSignExportPublicVerifyWithPublicOnly(MLDsaAlgorithm algorith public void GenerateExportSecretKeySignAndVerify(MLDsaAlgorithm algorithm) { byte[] secretKey; - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature; using (MLDsa mldsaTmp = GenerateKey(algorithm)) @@ -153,7 +153,7 @@ public void GenerateExportSecretKeySignAndVerify(MLDsaAlgorithm algorithm) public void GenerateExportPrivateSeedSignAndVerify(MLDsaAlgorithm algorithm) { byte[] privateSeed; - byte[] data = [ 1, 2, 3, 4, 5 ]; + byte[] data = [1, 2, 3, 4, 5]; byte[] signature; using (MLDsa mldsaTmp = GenerateKey(algorithm)) @@ -312,6 +312,18 @@ public void SignData_PublicKeyOnlyThrows(MLDsaKeyInfo info) Assert.DoesNotContain("unknown", ce.Message, StringComparison.OrdinalIgnoreCase); } + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsWindows))] + [MemberData(nameof(UnsupportedWindowsPreHashCombinations))] + public void SignPreHash_ThrowsForUnsupportedAlgorithmCombinations(MLDsaAlgorithm algorithm, HashInfo hashInfo) + { + using MLDsa mldsa = GenerateKey(algorithm); + byte[] hash = hashInfo.GetHash([1, 2, 3, 4]); + + CryptographicException ce = Assert.Throws(() => mldsa.SignPreHash(hash, hashInfo.Oid)); + Assert.Contains(algorithm.Name, ce.Message); + Assert.Contains(hashInfo.Name.Name, ce.Message); + } + protected static void ExerciseSuccessfulVerify(MLDsa mldsa, byte[] data, byte[] signature, byte[] context) { ReadOnlySpan buffer = [0, 1, 2, 3]; @@ -407,5 +419,25 @@ protected static void ExerciseSuccessfulVerifyPreHash(MLDsa mldsa, string hashAl AssertExtensions.TrueExpression(mldsa.VerifyPreHash(hash, signature, hashAlgorithmOid, context)); } + + public static IEnumerable UnsupportedWindowsPreHashCombinations() + { + yield return new object[] { MLDsaAlgorithm.MLDsa44, HashInfo.Md5 }; + yield return new object[] { MLDsaAlgorithm.MLDsa44, HashInfo.Sha1 }; + + yield return new object[] { MLDsaAlgorithm.MLDsa65, HashInfo.Md5 }; + yield return new object[] { MLDsaAlgorithm.MLDsa65, HashInfo.Sha1 }; + yield return new object[] { MLDsaAlgorithm.MLDsa65, HashInfo.Sha256 }; + yield return new object[] { MLDsaAlgorithm.MLDsa65, HashInfo.Sha3_256 }; + yield return new object[] { MLDsaAlgorithm.MLDsa65, HashInfo.Shake128 }; + + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Md5 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Sha1 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Sha256 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Sha3_256 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Sha384 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Sha3_384 }; + yield return new object[] { MLDsaAlgorithm.MLDsa87, HashInfo.Shake128 }; + } } } diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs index 754c1e64fc7..8d9cbb81a3d 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs @@ -3676,7 +3676,7 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) new MLDsaNistTestCase( nistTestCaseId: 54, algorithm: MLDsaAlgorithm.MLDsa65, - shouldPass: true, + shouldPass: false, // SHAKE128 does not meet lambda requirement of HashML-DSA-65. publicKeyHex: "D8D1170517D75DB90659838E13D45E98ED20D1961D98AEC16D2F10C51DF289E7FC4ED97D52166C8C" + "913E7CE9D2CA02AFD7791B95E8F2919F7487F9F1C6B0FE2133E2227FC405FD890DEE8C1B79114C32" + @@ -4015,7 +4015,7 @@ public static MLDsaNistTestCase GetPassingNistTestCase(MLDsaAlgorithm algorithm) new MLDsaNistTestCase( nistTestCaseId: 76, algorithm: MLDsaAlgorithm.MLDsa87, - shouldPass: true, + shouldPass: false, // SHA-3-256 does not meet lambda requirement of ML-DSA-87. publicKeyHex: "E4C74427766F1AE8399213E114EFA1EEFC7A85CD583C28B38EDFB5AA2351698ACABF5487E7B721F6" + "D15D5A60E0D0B629C663D2EF7007CE21C574F3F01A1D9C7A9A80E4DED8B3D14E3996C9FBD4018390" + diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs index 7708694c275..60fa07254d5 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/HashInfo.cs @@ -32,16 +32,16 @@ public class HashInfo public static readonly HashInfo Sha384 = new HashInfo(Sha384Oid, 384 / 8, HashAlgorithmName.SHA384); public static readonly HashInfo Sha512 = new HashInfo(Sha512Oid, 512 / 8, HashAlgorithmName.SHA512); - private static readonly HashAlgorithmName HashAlgSHAKE128 = new HashAlgorithmName("BOGUS-SHAKE128"); - private static readonly HashAlgorithmName HashAlgSHAKE256 = new HashAlgorithmName("BOGUS-SHAKE256"); + private static readonly HashAlgorithmName HashAlgSHAKE128 = new HashAlgorithmName("SHAKE128"); + private static readonly HashAlgorithmName HashAlgSHAKE256 = new HashAlgorithmName("SHAKE256"); #if NET private static readonly HashAlgorithmName HashAlgSHA3_256 = HashAlgorithmName.SHA3_256; private static readonly HashAlgorithmName HashAlgSHA3_384 = HashAlgorithmName.SHA3_384; private static readonly HashAlgorithmName HashAlgSHA3_512 = HashAlgorithmName.SHA3_512; #else - private static readonly HashAlgorithmName HashAlgSHA3_256 = new HashAlgorithmName("BOGUS-SHA3_256"); - private static readonly HashAlgorithmName HashAlgSHA3_384 = new HashAlgorithmName("BOGUS-SHA3_384"); - private static readonly HashAlgorithmName HashAlgSHA3_512 = new HashAlgorithmName("BOGUS-SHA3_512"); + private static readonly HashAlgorithmName HashAlgSHA3_256 = new HashAlgorithmName("SHA3-256"); + private static readonly HashAlgorithmName HashAlgSHA3_384 = new HashAlgorithmName("SHA3-384"); + private static readonly HashAlgorithmName HashAlgSHA3_512 = new HashAlgorithmName("SHA3-512"); #endif public static readonly HashInfo Sha3_256 = new HashInfo(Sha3_256Oid, 256 / 8, HashAlgSHA3_256); @@ -59,19 +59,11 @@ public byte[] GetHash(byte[] data) #if NET if (Oid == Shake128Oid) { - using (Shake128 hasher = new Shake128()) - { - hasher.AppendData(data); - return hasher.GetHashAndReset(OutputSize); - } + return System.Security.Cryptography.Shake128.HashData(data, OutputSize); } else if (Oid == Shake256Oid) { - using (Shake256 hasher = new Shake256()) - { - hasher.AppendData(data); - return hasher.GetHashAndReset(OutputSize); - } + return System.Security.Cryptography.Shake256.HashData(data, OutputSize); } else #endif @@ -97,8 +89,6 @@ public static byte[] HashData(string hashAlgOid, byte[] data) public static IEnumerable AllHashInfos() { - yield return Md5; - yield return Sha1; yield return Sha256; yield return Sha384; yield return Sha512; diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs index 08e9e507176..5f97ca8d3d5 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/MLKemBaseTests.cs @@ -637,126 +637,246 @@ public static IEnumerable MLKemDecapsulationTestVe ); // The vectors below are generated from the NIST ACVP projections. - // https://github.com/usnistgov/ACVP-Server/blob/85f8742965b2691862079172982683757d8d91db/gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json + // https://github.com/usnistgov/ACVP-Server/blob/112690e8484dba7077709a05b1f3af58ddefdd5d/gen-val/json-files/ML-KEM-encapDecap-FIPS203/internalProjection.json yield return new ( MLKemAlgorithm.MLKem512, - "8D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A21791", - "FFB93E594AB462B4070F2684B3845649B96474760BED1BAAD22A38B2667B7765C504B03D65EBB1B88B613C978518428097650320821454B971C3107962E00E4A575EADA990B1B945BE845FB9411D9C8303224B7CB1D27E0286213C1AC1052C363ACA3B0C053FAF48577FE4107BF35343FC39F7A5305A98AB2CC315A84C5C60D9940E409D65B63BFB3694FA249556F87BD27C28D00A62A3299FBAC0501A3634A11267584A216F365614563FA327686CA32B38E3102E7305E48A7DE910737E688351E94DA054CF1D17944305678000BDD9CC8B93333660A85AE6B8C4612A6535E5AE8C959125141E6536AE662C741AEA0D783B53962B5CC612750AB3AEA3708445EC97B2BA1EF3589CE9F94D3A4B91E4052A746635A595568640B375E5872E30777137874A429A4741AA81CA63A90884E54527A48B84F274C0E04B92386304D50048D78713BE0A9008A69DD49CB886CB6E7BFC7CA9EA03F09896D739C292C3021B2A985CD858DE5A574A7C431CA3795CDC436EE58596B10A1507B60267B1C735BE22E05F5E6AAA12F132FB932DC815B2411CAC97EB729EBBA95D5C1CD7280A339CBC56E85D00763A1B6A371735CAA1B8A699C431EFD2182366AD4E7B4765E9A842ABAB175128AD4127BA447157F56098B3C14C561502406531FA06863C85A406494CF330E591BF58FC0216B9A66CFC39EC26C10FF97FD50017CEA705363B0BBCC9874BB2BCD0AB08631140923AA88E0AC43531757C689F3F075FEB3B59767BC1A327C1EC8A7E0670415ABAC9D0CC1D7854620E8339B5456E3D5A1AC3562E8F78808611CEEDB57BF0DAA937CC8E2C1780DAEC6FD08ACA72876EE010C290AA6136EA91E71605C6F2BEDF89B9519A5AA353C3E7415F4D4915907461C1A0559CEC7232F7A90A17821C84864739CDA43C7C94A63197DA4EC3E82DE870CCDCE4988DAB713530B8CD889A010A769DFC148CC896C2AA00AE28041B4AC0905373408082992142F61B817152609759807105C2A43C508FBB4748F094DC4A2EB6330A70543B405CC34D1842F6711B41F790E82316F6A44CB99262FC4338455863515AB67FE6898D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A217913DFA277AD62F7CAEAA930284E348256EDCCA5578A06528678CBAD23F0A8DE1D40BAD0A76BA218C111C0DBB15963741113EACF5407A795D689E6E1EF1DE8B0351", - "C9C81034C5481BCBD90DEE95F277DEAEEDA9240AC844B27AF04C5351256B3B2122C0FD22F18D82C82C80875253EEEA45C3F7F2C4C40F321412460025596C196354E14D870892FB2A862E52FDD3E77BE07F500417F29784D3D2FAA477F10406C5FAE13B1B925B1ECA3FF4C8C3AF2F7A14CD30C301892EFBF0DEAE245DFC3816F32A6641C208E800E3BD3CE678013B70D0B588174E6AB0E03D095F009EB301497E6E36EBFD215FBFFCD78EB9D8372B034525CB41EAF5CBA3D5F2F434F2F6B85CB011E97475F5252D6407C92A0467286646E8CC49F669E6C6579ABFFD28F4451241BB559027F37BEB0E4EC110519C5D3C5C8F5A39A67681188F9E173FFC1601D35F79DA24462B1A4FF5A04EC9C4C5C0F4F276E4807DAB94ED35A7B1F99D78BA5F767F9D6FDF1CE4C01B696FA10F49CB500CDD0CB921665FEE23CA153AB9E823BA88B944240FD6638D261B06FDE5302CDCBFF66D2E55AA6DE9C14CC177752513BEBF6C4DC3BE8C293285DD0F643A11A31293419B34D4B18B9A46223964DD7B8482D96E27449E85EC16E663D6AF2B85A1B630B84CCB87CCAE6DEBD515A5A2D9B05BF0324670284EA5F1ABE69BB4B6EFA261712A28CC520CB72881DC7DD788AAC865BE8B51F0BF414EA7B8CC9F4473AC2D03B73FD9E9A7CCDEE38C7B170FD5A34FE562ADFC41E8E45957CE426F6432001238CA36B5162D79FB3C9FB6A9071E453C8E9CA05CB52A859EF21C8051E8B8DFEDB5370FA9E57A45B04FE383394F72407BA397CCA87E017B32D22673F50E6E1244A81DDD6B381BC1E67099484DFCD087E7BDF479A8AF559D7893671802EE10D114379480E4DC11EDEC1605A81059C0D40400B3032D50620F3236A28F068D07FC7EF14121FD4701763AE2A8E4731EFF8D1C103EE4DB6B89FE4ACEB94C5F78A7CAAF5FE2D28831A9213964A8782EFD2170F5B2D966C49181BDA6CAC6A22C7A6D65713DB7DDA24537A711B06E7B0BF975C22F9CF33B5A7D6B5E3903AFD353326EE33D755DC747D76320FA8587087B9F5D106D6C3792B4BB25EDB2ABBE2699C7FF3D3B8B65919E508A5BE06F2D2138A1BEB2BB136F", - "57AE473989DFACA8266BE8C640B4CADE4DA7B02280E6C9D67612AD4B975381E9" + "70EC19B39348974173A550A5C52A248E191D46640799A4365F3C254757350B65764984180A9ABC9048679D6A84C61B7405EC82A403B79569C024CACA55D79BE23C943C159DDADB17011820C7D88D54071FC8AB142727BE747BBD253A26E92071DC34716F5037D1988A889302621A8465D08ABFD2215D97575D730C9495617EF3B69D0C7AA79965CA985BC147797D9688116A20F9626BAB1997FCEAACBFB439D655A566B0A4BD08472265439C00CE487955EBEA094AD00A6A5AC6FB9359F3C11A6E4B3B6C714F70F8A7B8B6524572B34B758DA270753B697415A964170374548B9D1FE43FD80C62A4D951E28182F2848B044A8352E11F5198547B71215E6287DFF13A18287148277883926396D9A07C0B0139577E4923AC41C9C31F0B6067C88B94CBB9921513ACF0AE80D7779D72C666B256B72A777B56A2D12007797B7BE6657650EB42B1060AADC5157FB819EBF707E51637CD8469645196765A2EBFE8483D62C5E2422C27BCA84E5A0F69F45609928A7E51948A9464D5093CF463A39C26447126C684160F3A4298EA0B5B0973A15403CDDF286BEBFA587FFBB5BFA7692A404ABE3BB14014AEAC418900E4588676A5E7A21553F50037262E3DD6253A8BBD985A679F638F709545AB322F6DE71192FB60C0A368A3B06C8CF5267D792D6C2518EA0A27855635E3E68891C141123A1F8C80AA5300B151AC9AE4342334265C457CA8809891EFF12B398A8465F25508836EE3075C898822BA7675AC359D80E85FF84112C8502932016E24531FB24AA0F744B8252B3D89B4A41721BFD779A826AA46F00720B9592A12307B27EB2B5502987AB477161B72F31BB8EF2C2F4EA83823B72CB16532768508835852A701C3522A7B71DA1CD8B5CCA512117990709797C8AAEA3B300B79A28460D22A2C3527CBB8529AA667064FA2039E22AD5ED740BFA353EB04B74A9C9328266561A76A12EC2C33766697DABBDE92A712B81712D2C4E1F335AA642774441E917650F8D92278A8C0444214A774B7996463527756935171D9FA61D0B50454F74ED50831EB3138DB7374A35387BBCB23E40388BB9228C3A66CDD2222524D7CB8DAE2E70FE3D97847AC35824F5D58B54DD943A440DBFF421642", + "54301038DA5911366D16C417BFD96AEB85C5DA4AA45AF32F88A700BB9A973AB62684A052D793379B3C2B253B01A4E512AB34C8D8A76F5EBA5F1B28451A66632872C489F3CA606C6B36336895C032386BB35E98B43C8136350616CCF82A4C24816F4354B7C197940A62537BB36F2B8DE32A6AF6CAA100845FB62184B82B29DCE2662CA94D93FB027DB3C8EF858D4223540E79AD5D204C99637FB66718CD04782E149A07354D6FB2C742A9849506BDDECC0548367421FA2B8599443C74192D6B4B67CC5E16F8880087AC578ABCADB5492CC1AC6916CE73AB2858797134676260B22B28B4A8917C5ABD876EDA706CE381AA4985827D492A736652DD6C1DADD10ADF045DBF416158B0384A991D8501BAA9A714B82788C263C16858C81B978FD353126222A46E1587718872BB11513CDA3A88B6547BC464CD612548E581DFE106382428BA8452A86AC6ECB50B7B3C1CBEA571513C63B8741A2CB82C5055CDB2CB00CE9036C220A25C1BA21891B520D435342136D0C15AAFC12DBCC810E9C256D397A3D23A6287282AAEC038649151886A19F9B583806839EE86A12D131FB3E6A1CA1C9CC48626037B5F3DA74C8A025CC61A76078B07D00AA6DAD32C4147CDAADB4DF644A8DBF4222C47AEEF774BDAFA5A48258BDEA84E7B8B6A5CA09243589EF7F1C249A2B344068FC8D874C33B6C4C2782EA86AADE7C10EFDCC93FB993147A3B636127711195C121C7506759389373F896843991125D5A0AB8FB34595166A9109DC2D19AE2738444716C9C21BD06DC8145458ACBA30981A95F8E141BD17B17A3F645E9B63747E370E8D873937A858048614F0645F4B461EF769D2A696706C2811E756163E4746BF00CFFC556AD7A2F0804A6BEDC6A59B1546727C602A99397C50FF818721D5319F63B058D03BC9DE57C1DB74FE14A0D083C25B17886200633D230946DE0A148781735555CCE797040BB479FA733C2A808EE1CB9A285CF863CBDB47172F3A68EEA614736C73C71FA4AD82C6CF13C5CD3179AD296BF3BD6815D13CBFF75A3A99B4824B7560227BE0BD809BD43AED7D951ECDB7273719560DCC0E8C13F70EC19B39348974173A550A5C52A248E191D46640799A4365F3C254757350B65764984180A9ABC9048679D6A84C61B7405EC82A403B79569C024CACA55D79BE23C943C159DDADB17011820C7D88D54071FC8AB142727BE747BBD253A26E92071DC34716F5037D1988A889302621A8465D08ABFD2215D97575D730C9495617EF3B69D0C7AA79965CA985BC147797D9688116A20F9626BAB1997FCEAACBFB439D655A566B0A4BD08472265439C00CE487955EBEA094AD00A6A5AC6FB9359F3C11A6E4B3B6C714F70F8A7B8B6524572B34B758DA270753B697415A964170374548B9D1FE43FD80C62A4D951E28182F2848B044A8352E11F5198547B71215E6287DFF13A18287148277883926396D9A07C0B0139577E4923AC41C9C31F0B6067C88B94CBB9921513ACF0AE80D7779D72C666B256B72A777B56A2D12007797B7BE6657650EB42B1060AADC5157FB819EBF707E51637CD8469645196765A2EBFE8483D62C5E2422C27BCA84E5A0F69F45609928A7E51948A9464D5093CF463A39C26447126C684160F3A4298EA0B5B0973A15403CDDF286BEBFA587FFBB5BFA7692A404ABE3BB14014AEAC418900E4588676A5E7A21553F50037262E3DD6253A8BBD985A679F638F709545AB322F6DE71192FB60C0A368A3B06C8CF5267D792D6C2518EA0A27855635E3E68891C141123A1F8C80AA5300B151AC9AE4342334265C457CA8809891EFF12B398A8465F25508836EE3075C898822BA7675AC359D80E85FF84112C8502932016E24531FB24AA0F744B8252B3D89B4A41721BFD779A826AA46F00720B9592A12307B27EB2B5502987AB477161B72F31BB8EF2C2F4EA83823B72CB16532768508835852A701C3522A7B71DA1CD8B5CCA512117990709797C8AAEA3B300B79A28460D22A2C3527CBB8529AA667064FA2039E22AD5ED740BFA353EB04B74A9C9328266561A76A12EC2C33766697DABBDE92A712B81712D2C4E1F335AA642774441E917650F8D92278A8C0444214A774B7996463527756935171D9FA61D0B50454F74ED50831EB3138DB7374A35387BBCB23E40388BB9228C3A66CDD2222524D7CB8DAE2E70FE3D97847AC35824F5D58B54DD943A440DBFF4216429146E2AC9383962420545163D6F82456E1B93E22A1B2E6875ADA12D4E194AE93EF5C3485EEBBE1BB13C560480DC3471CD950EB300CF2D18F38CAE7575B133526", + "9068502093766BB27635F12F3569794C54227CB1828128AEFC5B715CDCD1E9080D59FB218D17EA0D212D158DDB5ED0FFDB4FA9401F4F23387D32AC8B788CFB7A319114425138744002648B07D5216A3EFB4964BC72E98A6EA2939FAF372CAB44CD5D8A929F66C41D644118ACDE5DA2F09B87F8A1F41F55924A7784D8552790CDF256958E35324381902D9A006FAE02933B017A8E55931B6A0CC8CE3B5723D85DE4C4585FAEC0BD80986224CDAEA443556EBF8BCFDE162C258B9E0AB00C2B9DE0190384C61988BCF362BD0493D40D276FFE4873811EF2851204626342921BFB6A75EB6079F58C030AB1D9C1844078E61C29DB88B5FDC463B7AD3F770E1CB8B526BD9B9A5AFADADAED0368BEE0FFABD9ADFEB0FBF6E6DC7A36115BA47A292D454D7A31F5601BD8BD5435B2EF464A474E37B12B7794F356F905FDBEB248B44003F2B43B925CDB98017A68A15B8B90E2D6DAB1B72AC2921CA92F55B3453C2865DECC094E77EC1E70F99A14CE22BBBF7D3C25F1ECBF96478D84DB4EB1F5E077777214CDA31165C2790172EF778435B56B712E3C5C6B2FDFA3B40B45F7065731EC1E33A8FB300F9FD1EAB14A77E5D8367329E0F834A76E889EC2C8F80E5C1098055F2D517EC381A01F37B1AA3923894D90E1A25A8F55D3DB782ADCD644A1B8A168BBF263C77F34B1A3388E76528FD4F91BFDD7D6499EF99CF663964421FFBB6C17CA9456A2E6A3681298628FA728D3FCFB3BDB65A22E7CFC962FB83007F249D543696A8EFBD9A3DBC7C090F2C82B38E76ACB653F18E78407EFDEA120AE61CDCC8C28CAD984D776B69FB201BA3E154F3C87F53CF84DEF777E50BE420DDFB9734065B8D541F983E69E7FB2B48A186BF8338F3234A0B785B2BA63AA875B28EEE98843C48F60BA500E93067F283155A21905836AC33CA8B06790DD800DD000CC42171775A07F704229FB6F9E5123ED032148DD0EC616530B98A68BE3DBAD2A5D24FFABEFD6D78F4484C8A9969DB7480F54A3DDAB445D3C6C489A9E296B612591A027D624032CD1B11452FEA69A178006E8429BEAB1FC089098BE7EA3D73518F3F5E7B59843", + "32FE0534E517EC8F87A25578EA047417EC479EECE897D2BA5F9D41A521FAEDCC" ); yield return new ( MLKemAlgorithm.MLKem512, - "8D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A21791", - "FFB93E594AB462B4070F2684B3845649B96474760BED1BAAD22A38B2667B7765C504B03D65EBB1B88B613C978518428097650320821454B971C3107962E00E4A575EADA990B1B945BE845FB9411D9C8303224B7CB1D27E0286213C1AC1052C363ACA3B0C053FAF48577FE4107BF35343FC39F7A5305A98AB2CC315A84C5C60D9940E409D65B63BFB3694FA249556F87BD27C28D00A62A3299FBAC0501A3634A11267584A216F365614563FA327686CA32B38E3102E7305E48A7DE910737E688351E94DA054CF1D17944305678000BDD9CC8B93333660A85AE6B8C4612A6535E5AE8C959125141E6536AE662C741AEA0D783B53962B5CC612750AB3AEA3708445EC97B2BA1EF3589CE9F94D3A4B91E4052A746635A595568640B375E5872E30777137874A429A4741AA81CA63A90884E54527A48B84F274C0E04B92386304D50048D78713BE0A9008A69DD49CB886CB6E7BFC7CA9EA03F09896D739C292C3021B2A985CD858DE5A574A7C431CA3795CDC436EE58596B10A1507B60267B1C735BE22E05F5E6AAA12F132FB932DC815B2411CAC97EB729EBBA95D5C1CD7280A339CBC56E85D00763A1B6A371735CAA1B8A699C431EFD2182366AD4E7B4765E9A842ABAB175128AD4127BA447157F56098B3C14C561502406531FA06863C85A406494CF330E591BF58FC0216B9A66CFC39EC26C10FF97FD50017CEA705363B0BBCC9874BB2BCD0AB08631140923AA88E0AC43531757C689F3F075FEB3B59767BC1A327C1EC8A7E0670415ABAC9D0CC1D7854620E8339B5456E3D5A1AC3562E8F78808611CEEDB57BF0DAA937CC8E2C1780DAEC6FD08ACA72876EE010C290AA6136EA91E71605C6F2BEDF89B9519A5AA353C3E7415F4D4915907461C1A0559CEC7232F7A90A17821C84864739CDA43C7C94A63197DA4EC3E82DE870CCDCE4988DAB713530B8CD889A010A769DFC148CC896C2AA00AE28041B4AC0905373408082992142F61B817152609759807105C2A43C508FBB4748F094DC4A2EB6330A70543B405CC34D1842F6711B41F790E82316F6A44CB99262FC4338455863515AB67FE6898D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A217913DFA277AD62F7CAEAA930284E348256EDCCA5578A06528678CBAD23F0A8DE1D40BAD0A76BA218C111C0DBB15963741113EACF5407A795D689E6E1EF1DE8B0351", - "4D18E11B61F670F19330C7893B620DABD0E01B1DEEDEB2AFE73921078FFCA2DF210EBA11AFD214632ADEC9E136A35B4C90C418CD1C3A4E7895FE8400419118BBDA76486F26336646905A633C0E5EFDF8EF0DDDA6BF759DCB2873A9F4F9894A8B075FA763E07F96EFB540332E34BF8273861D0CAEA2DA268130CCE8433C0D457F9FFB2B9657A6FD277DD93157FFB9DEA6EDC2D3C30A069C999A49A45D59C2C4BC152077A8F063B3DF095E58F366A724342A4AA9E3440A867B98CAD924D5DAB546259AA48026E57A4A8E5B8FC1B4FF0D29B5149EC831CD0A5E6FAB4DFB9AFF96B2B1E5E8444084089C88A0435B57DE995A3A627D17CCEDD937C765DC72BC1C04B689030228FE9F127D0363485A53EF4F8800FB39F6DE6733ADFB77D2850EB2A26B30E2DB37F1EC5B4A40979CCD0D7746C7085285F6470200611094C0C83C0327E6308880F9D846F0B51F297660239B3F381DCE91179C3E58BDFA9BCF86A6EFA0E8A5BE21DD9166C7508FC4CC634E7224F27085CE2A7572EB21AF4BDF05680E8397F6989A3899356294AEAEAB57C9F039F4123E84D1A2CD4F660615699373662EBB9367A2EDFAB31801CBB5E0900FAEF108AFF7F8819A40BF5D794067BB5F72E840903B9A318FA998DE5F933B5DA834D3E2A0A4DBA54EA8F538DCC6114826AA1B5CB32A31981950AAC2D0CDB2E23DDD155D4890CEC21F56AD686179E1E51D136D733BFCBB95EEC363F1BEB25151CA019002451613C7431D9FF6E00F7210E641C9A53CACDD54C9A90EA394C0E88B547B6A637B98D8C894009A18D22774D979DCA660CA1CB3557326D2A24719549770E7C533A17C4B18C8CE590ADAF9FD4721D7D74CC66D1C252D99C5082522900813520080BEF39C3517FEA9D0FE404EAB5BE97F8E4444FF63BBD87123944E0B6BF91B7732FBBF0AA877F507A8A5DDBAC7A96525ECA11B3BEBFAB1A9F88A4C0D80E85E06D3EF9A2CF32BF4D186FEDD7B5C6D8664CC8F2F8B8C7E999EC42D36064CA0D363AB3B1B14A41C09C434F8591735285EBE4BDBB11AB4B16A25205B9CE0A73938F9C97799A0DE80747D56D98D7E5A6231F9ED", - "22D9E05E0D01B56BB5042AFB69D497909F66B47CF236E9C77FA06F9D81A16AFB" + "770AB5FCCA728F659556C212F9925F28493CD3C2A60AD743830769F9B387422AC46385C88F4A10D8C43764F5200E810D20AB9A7AEB5C8B100CB751C55B301976D7BD4F0A1DE7D7CFBF0379CC6B9844B16749B8C6659824B65C2659A430914B322289B88D51324772C4A507CBAF240436AAC23950088E41973FCC487F57BD1D14321664AFC6EA2B66403C881509BE445933528A4F97C2A5B86F1CBC08816484F9432241A09E16D6B6C7068F0356505227216127AF9506250E59ADA3AB4611D7BA4A999621241A3D8C4FE0E7CBAE2492B6F44E6AFCA27F33940E3233F5A382549B9DA2C52B9BC99A8BDC1E541B274987A5BC4A272F330F725856220961C659CD9BA534716C5A113B53CD243D5C907FD6E1B2CDE69090B40314B7CA85F2185F9401FA758C3FD8AD91441A6DCB88B7350B753CC06AE5A1FBCB4DF61CAE1DFC7E60C28C7787654A068DD06821983AAED658C110BC19C2FC61E76CAA65D9C0914887A77571B3E63CD63A437028BC03DC8F69346585D023F01465E430220607948619975FAC993703CF60055D9AF28EAA1A2CE412322D11497DF22137380714B701DAE205EF308E2EB8A1B0B09ADB896BB8AB3F34F9BA2695056B7785FD51ACD043CDC1919C6B0335D7E7BDD1C43693582ED5E71D534163A48C45796B43E98BCB3DF47E075B8AE3E96A640CA659747B287C4714113DDCCBC83D37C54022CD321409BE74C331900CB17A72DC27BB6D4401D974B4E236B82F894EF5DC9A7A29091AB475D584B52D9672DDBC8D63B0BDB51554709041CC07CDEE435F39463C04BA0DC2B4C085AAC7822AA4BA50CD470A75C53A7C1318839DF4086D8A8D3510780081112453134F15601F810895B287195866FC237669F5B212C002F62B2130952B99BAC4E0AB002FA915520A715A41B1D541CB54CB7DD0291655F14FD2D0B3D802C9D6CB569FC815B69B1A0787463104A30AB34E7BD732FEEA3C8CC8764FE199947513889942B7C110482C9A1477348C3C3B491060A78B8299490E4DBABD22B054929BA77EE31922E1439D15B530A0C307E72C2F9C568622301DFA261C885A6F66399DC79E593486B11FF236B8367BF6864A1A596448FC251898A3C89CCD0B551131182654", + "3B5879284A33A6204C06F84BF91843CF9B23CD8256E3D23BD1012325686138F40E435275298A614D30950D98B00F59AE6A04BBC37510D4DCBE738B90530B455B048DF4F4AF191B59DB8A3D37C83190D425D40014775B507D43A2E2204B9AA6B6241057663A782A411419F0A0E1E8A4D7F5995B197114E832C7FAB5F2D69923D53A46F07C403038C29219EF228DA1746ED27978D9723D09EA6D6F32856D8B5589382AF4F32D2DDA0EADF342ED3248EB0CCB7B9424FCE6432F8A3892A24D610B9F35B7A4D63B918203BEF239C07277433D8122EDA503C3D596B7C670893051286044EA919BB4863AB6A7CD8D43255C099CE1DB832B109CC24C1B15BCA2F5383F03CC7263775AD39A90DE6A1E1CBB4EE8683295353FDE05478CFBB4C5249500FAA9D35B264E36494F009D8CEA06AC096FF3965DE5980B8E8485149B6912BA7B8E935341755AC67499647391A181158F3AC719F3B36CA0624B6C6F26800904609759B0C5D4270ACCAA01159C4235685D1B079624576C73F498A3F9A37B5090FD6010960C3EC9D7A1D95C3749DC3E225B800D2B8F3B597090F0B83CB315B7A43FB69151AD2B2EF21C8E3D6028A650716BD96F466BAEC316A230232B59A97D371C3DF6D2476C51C64F48271EA38AAE9C8EACD1A0F9318DFBC273D382CDFC0043B0C47B35834EB2069A0E306A53826C49C7A69AE3442947C37ED01F55E9411146870DA50194E778CAF71A7561429D1AC02AC362FAD196CE1331BF2A00001DA290F2B136B92B576C2831717908682412462AF101C3ED3685180112D41A73BB164553F9B79CA71F0932693A630E4209BEBE7BAA7AEA295150B1B827716F47464204258F414BDB6C5FFFC42249C782494A4268F60BC5C195AE9C1EFD778CBC15AF2003B3DAB7336AF5037BFB4EED702EC887AF43EBA616414914B08493D53ED9F89EC2805EA1B40B634610B458236A2ACA1610565350234E9B23BE27166FB8ABDB441138F44E79D8541C3AAE85FC553FB884CCA95E6C84325DF29E112B6D863444A52721F5A5A6D0DB5A65564A545633CB121A927136408C16763191EB10270E6A1604B486770AB5FCCA728F659556C212F9925F28493CD3C2A60AD743830769F9B387422AC46385C88F4A10D8C43764F5200E810D20AB9A7AEB5C8B100CB751C55B301976D7BD4F0A1DE7D7CFBF0379CC6B9844B16749B8C6659824B65C2659A430914B322289B88D51324772C4A507CBAF240436AAC23950088E41973FCC487F57BD1D14321664AFC6EA2B66403C881509BE445933528A4F97C2A5B86F1CBC08816484F9432241A09E16D6B6C7068F0356505227216127AF9506250E59ADA3AB4611D7BA4A999621241A3D8C4FE0E7CBAE2492B6F44E6AFCA27F33940E3233F5A382549B9DA2C52B9BC99A8BDC1E541B274987A5BC4A272F330F725856220961C659CD9BA534716C5A113B53CD243D5C907FD6E1B2CDE69090B40314B7CA85F2185F9401FA758C3FD8AD91441A6DCB88B7350B753CC06AE5A1FBCB4DF61CAE1DFC7E60C28C7787654A068DD06821983AAED658C110BC19C2FC61E76CAA65D9C0914887A77571B3E63CD63A437028BC03DC8F69346585D023F01465E430220607948619975FAC993703CF60055D9AF28EAA1A2CE412322D11497DF22137380714B701DAE205EF308E2EB8A1B0B09ADB896BB8AB3F34F9BA2695056B7785FD51ACD043CDC1919C6B0335D7E7BDD1C43693582ED5E71D534163A48C45796B43E98BCB3DF47E075B8AE3E96A640CA659747B287C4714113DDCCBC83D37C54022CD321409BE74C331900CB17A72DC27BB6D4401D974B4E236B82F894EF5DC9A7A29091AB475D584B52D9672DDBC8D63B0BDB51554709041CC07CDEE435F39463C04BA0DC2B4C085AAC7822AA4BA50CD470A75C53A7C1318839DF4086D8A8D3510780081112453134F15601F810895B287195866FC237669F5B212C002F62B2130952B99BAC4E0AB002FA915520A715A41B1D541CB54CB7DD0291655F14FD2D0B3D802C9D6CB569FC815B69B1A0787463104A30AB34E7BD732FEEA3C8CC8764FE199947513889942B7C110482C9A1477348C3C3B491060A78B8299490E4DBABD22B054929BA77EE31922E1439D15B530A0C307E72C2F9C568622301DFA261C885A6F66399DC79E593486B11FF236B8367BF6864A1A596448FC251898A3C89CCD0B5511311826546E56B6967EE923E5733561D5A4BF940CAAC4960BF60CB769A40E396BFC370F094A00986D708AC731B420FDC11FCB071BDA0786A23F80269341AE270B8ED6844B", + "30991222B8EA47530F7C703D85BF4357F61F47615539781920EFFDF067172E32EF1BA77B21670ECA074C4B2401BB591B21CA0F4BFBA9F8BE4A26A9DE2ECEAA8303A91073C0C91205DAF6DDB17D35104969C5036BA722B176F6A3E6D92E1E5EDDAD9A6A3561F7E5338BA2B163702E297F9C6F27C5BCB7975139DFF287B739D2053BBC4307946B89DF3D9C963379B932DDBA015A6EA396E729996F7FF573A0C24040DE323E60B95B2197C89127661DB35D44588E132742B62949EA45D3E8527F0B2B71295E0943F1FA1F87D3B3EF11F840B59E2BBB10AA22B687FF23D22CDA109D5CE33F3527FEA041579793530226009D48CAE3E499FD0ECCD036D04B8DA21F939908E53F5BBBE41DBACAF3A7F9F5839D479BA0909F0DF0B2C8CD7AE8B11F160B16EBA19656744AC38D9AEE3A31E698380B3B9483E3A5F3C3B3767C519ACBB515706B1F192B16AA7B1E0B8178F28C65CAB578368DE5BD0DD5691B659293B3B212A5547E60727F69B33D3938A301572FDD931F5F71E7C647BF9CB4B3A8B294E2A17CF504319278648E59DA78F0FC5BBAD5ABC37551C30AAB853CC50DF796F308EC99D56A2348954EDAF7AF6E4D62FA6B1BB6FAC370226F47F1A91E2BC6731875C09CCBF8E635745DEF1A607F15BA774E7A1FCE8822C07916D352BF24DE6218350C5356D627411F884623496620500337654DBB8048D58DB94BCD8BF18ADFF7EAFE9DC8687156F426379FF0D57B880B8F86FD94861CF865DB231B9ADF9FCC53A7D8E5BEC45EF2EDEEAF2109F35A365C1287AC81D18EF302C9313B357870DB914E2E8300440A0C44E3940FAB6B35F1BC4BDF9B7A54EEC634897F1F715A334E553F2AEF6ECCD13966364CB942CA7C91A90EE2ED924DAD7F7A0907A56323BA787967F687E1C8BAB45976E20AE14301139E989E4257EC9F87728F4AC56A5F0588D96908FF7DD901AC4FBD8AB336EAC865377DCE7C22B4E8193F17769E1C1D6A2365D21715F014E9634834EEC80E4F6C97FDFDA6559BA2F88F81CA57A03AED25A0D818E7823BD08713E1667815A5E4776ACE6FB5658053E6DD38A01AA0AA9819802BD83E", + "6621D11567D58EAC3CDFBEB9C69DB0E7AFC4C97C252D98B4770C5F6AF98C83DB" ); yield return new ( MLKemAlgorithm.MLKem512, - "8D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A21791", - "FFB93E594AB462B4070F2684B3845649B96474760BED1BAAD22A38B2667B7765C504B03D65EBB1B88B613C978518428097650320821454B971C3107962E00E4A575EADA990B1B945BE845FB9411D9C8303224B7CB1D27E0286213C1AC1052C363ACA3B0C053FAF48577FE4107BF35343FC39F7A5305A98AB2CC315A84C5C60D9940E409D65B63BFB3694FA249556F87BD27C28D00A62A3299FBAC0501A3634A11267584A216F365614563FA327686CA32B38E3102E7305E48A7DE910737E688351E94DA054CF1D17944305678000BDD9CC8B93333660A85AE6B8C4612A6535E5AE8C959125141E6536AE662C741AEA0D783B53962B5CC612750AB3AEA3708445EC97B2BA1EF3589CE9F94D3A4B91E4052A746635A595568640B375E5872E30777137874A429A4741AA81CA63A90884E54527A48B84F274C0E04B92386304D50048D78713BE0A9008A69DD49CB886CB6E7BFC7CA9EA03F09896D739C292C3021B2A985CD858DE5A574A7C431CA3795CDC436EE58596B10A1507B60267B1C735BE22E05F5E6AAA12F132FB932DC815B2411CAC97EB729EBBA95D5C1CD7280A339CBC56E85D00763A1B6A371735CAA1B8A699C431EFD2182366AD4E7B4765E9A842ABAB175128AD4127BA447157F56098B3C14C561502406531FA06863C85A406494CF330E591BF58FC0216B9A66CFC39EC26C10FF97FD50017CEA705363B0BBCC9874BB2BCD0AB08631140923AA88E0AC43531757C689F3F075FEB3B59767BC1A327C1EC8A7E0670415ABAC9D0CC1D7854620E8339B5456E3D5A1AC3562E8F78808611CEEDB57BF0DAA937CC8E2C1780DAEC6FD08ACA72876EE010C290AA6136EA91E71605C6F2BEDF89B9519A5AA353C3E7415F4D4915907461C1A0559CEC7232F7A90A17821C84864739CDA43C7C94A63197DA4EC3E82DE870CCDCE4988DAB713530B8CD889A010A769DFC148CC896C2AA00AE28041B4AC0905373408082992142F61B817152609759807105C2A43C508FBB4748F094DC4A2EB6330A70543B405CC34D1842F6711B41F790E82316F6A44CB99262FC4338455863515AB67FE6898D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A217913DFA277AD62F7CAEAA930284E348256EDCCA5578A06528678CBAD23F0A8DE1D40BAD0A76BA218C111C0DBB15963741113EACF5407A795D689E6E1EF1DE8B0351", - "58A1D50BD43788B872FBEA3B765FD9CC911352CC7C4A6DF1C37B16B33EF4E58C4C94E4BCCE87E2F40B3FE6012216C49F0DD147EED2CEECE1909C626659C29363CFC9C5CCC147FA5A4C54A0755F9ACBD5EECA6C058E3BB27B5F4B762435A2F9C4C9F3F1BCCA10F49CF79AF6407ADECC839137936922E802803B906FAF2C2F61A58EA70256A8F344810CAB862A5D205D01D9454731143461FEFBB15216E3AF8E013B8AD62626A9B6BA3EC8D8E936EE95FA368FF8B65D0622DBB6EDE36B849066019A57FF0D858B6D6B3D577573688A7930440AF4DAA2EE22478FFC3230C2BFC28982B11DBB475C77561D8A1ADA11E5A79DA2ECF8519C2532B969BFED42B66B6B2052DC1D02B11640AD354AD11805D26CE1888A9B1971F8C0345AA5919B722F97FD2F13DDEDF82F275774928AC437016C7F917C67352984B0C1B9AEDC8078329E8B51DDE09FE46DD5056E0BB12C42FD7690ED529ED13EA628813D4BCF524ACE4A0C98856B0216872D7A3567392F4DD37713115A03993618E3CEA8D9B6AEFFEEBBBC27557612648BE6B3EDAD1B97CC99516E394C9A4888D5F4063F2A37A8B32C422195CB2F9E7E17D79DB17FAC28FD7EF0B327E6101B5733479FC73E4AB9EF654888715EC4C4E1FA95F1D4D6DD1BAE0AB249C371F6937C86C6CBC77BCB9A7F0B7AF45591EDCFB73903106001869B46D9894F7FB5FFF7A5079ED46CB0B596BEF936859D1E7B32820C2138B5546AFAEF00274EF86B179D796C5624143E8F500B8D9AC2EC4607088F97D74FE8183DE58C9152A1B7C510F7B00D82A0E3F8A0463D00AA168E238E0F19E6A14041624409AA4FE212D10664E6CBB0FA5D910A8494AD5054C69961444C3A34DE8BEE095F2E757F9AFF846A8AD0F6D3090A29789BDD5A59782F80CE081618A407B58C9E2AC05866AF57CFE915F261D18BFD29C7308383A716C75BFE357240A93AA410941656D62F0E1C3BE6C4487594E00838523E1B88B68A68C7BFCE22EB805C91E6E2AB3E0369EB4F077B3064B2106ECDB7FACB419631E8128B1CE21BFB51F52C2B0841160A4815E0524FEDAC9A75D014C47ECBA9580E7FE9", - "6D7A3AC0A410D5457233E862F2BC5A4ED3A5ADA47070A888AAC44599AA6A6E5A" + "22664886862835E6188D53C21FDC5EAF7849E078832E004CE79A7BBF122E6E59885608002C170077E98440039870E03FCB890D94001A98482EE6644097FB2BF39A93DA8811B951C6B905229A40BB97727EFAC92D266C4AAEC5623C17C1982A25D4859E362A030D191BD9E11D5CEB145E7482FFDC38ED17AAD859BE642072F55B4EDAFA4AC438B3DFB793A910BEA792780A801E70D2AF76283B60238DEE9A63011C343A586BA54CBB0C77CBBB3C8470C09F1A9C57A42436D3ECB89DC0CD711591FC674878A8317BB833D8DB10D217CC02883A1FBA2CFE3770F46721A7C9AC0045BE9F14487CE6992CC0CB1871CEADC3BA0627CFEBEB974B457D3B7953922CB0F5134918B006CAC669FB0B180BA00FEF56912B99A2C23B095E0A1F65F5611C879D4B519FB7E27153284725749C8D321178BB83C33AA9B547129E780B6C958E69192090FB3E2D69AF3B44A923276B4D5998A3349E5E291291B613B579800B12BE0805063755032A219916A5B9807A7A74A0A833F14F2F940465D970EFC7B7F8D93AE6D554A61085BE277DB5709AF4F1AE3F331B6C8900B24697978B7F69F1B3800B3606F23D90A683E44995F4A1451FA4322E03BA4E32120C5B6E6F8218B67A42D2A54467D672297B4F5CF51131180261276548F1ADD6C985415C15C3D00D83108BF34A6077EACCF7789865341B9594AC3C3781D15336696325C811842335AA43E2146B9176EA251ECCEC7F3E18C8E7F11CA7B09AF0CC14995515D80AB090711520D9BC8CD7353187BCD7D2BC4FD19911E11D904959617B4A30EA844E6292CDE42E46D2A013635C1C38C2D42BCFA68C928B6196B9EA75E6626DC7B17849205838B4C794511DED5B19CDB76CCFBC175F6B94E4E5CC5FC3C940C836C7F86BCAB3BAA860CFC3F1C8C088ABC684A243DCA306B27C2200AD1A31261B4C3C163B99E3022D8F79C9B4989AFDC32F5D93134FD57AE2A7B8381319E9FC2266F457CEE24440307417429AA259CF7DF5865A290404D73FB638BA6341316D8AA69FF605FD23453C34BC015B915D723815285FC200966C03CA84828A37579C86418D5433748669A56C447FCAF3F7A27F8BE433449CF232282A0FC0F55F6387EC0CDBAF615987A153", + "65BAA3F5C74319F488D378CD416C312E8B5FB189A3991741B4035E1E15B261E350004A4DA438725888AC54BBAA2C9406E303CDB2D9765A0352A22A28BF80CE51CB4234397119B3C5AAE2324BCC0FF6620605373366A474621A949B90888A12BA91FCB68CC9C42070B2AFCC54095236497583DEE7947A3258A6D33672C2B1FE8A02EA9CC34A045C91C5AD3AB72973888C46B8CC383015DC12476551BADDE250D2D84E7B06B7D5984B55A6918023C41EC9648CBC706BC61EF3C041C96822265C092DF204BFA25A9A16754B165AEE58607F2CB9BAFC05F548164C96483A846C3892A6553422E99B1D0099B946FBAA4C320D8187BA9928C574B448613B18EC7BA7AD5C4042642FD04260F5E5600E22AA69051642D0A2AC2BBF5142B69A69B4865AC9FC8B25F71B93F8CCC2C601717D85AE5267116EEA467F54656999CDB365076CEB052D4B4698B361C0B9B02B7BC10129972AC64B1CC65EE0AAB59D401AB41A245BF10F0D58393587CED798786EA87A56F48121E3CF0420BDB438A4E292CB33B6B371D8850D290C8C93627D2B428566014A82AAFF496E809BAC64538A2A52B6FFAA0852574D8A648A5CE81A17471EABF3CBE2F34B6E54C01CE079CFF4AF0CC60F820C64BA30755B20CD06420BCB9156055624599C1F8B8292A668468BE0836FC47383EB8B74E2118E918FC499C64E146276B17E5E015BA85863D9920D8A299F90CB09C178018B895CE6F0828246247CD0B9C86B4F885350CA6167E90953E9397B5EDC0A71866C087A9A8C1A6A3E895BAA78303337479AC256BAD692FC0A9ADB58C2A152A9E382B11956AE30263E74AA7BF1D79B3B98800B7C82E81A0C3AA2CBF4A8CC1D13B3ACE8B3502361ADC694E7684278164C810642771B04085122DD408228606B939550892B01A05B347B2135B5568B4E13C250BC1CD14396A3B756450BC864D7C9346CA4879178DE1A0D5DD82E09F9A938B40C37C4407DA787DC7149875C3E927BA166528054001FF103BFCFD2C1AB933C17E10F1F12779AA44207C960BCF7330D415832050713B438C0482651A5B10B850A828964EEB26196A84AF4AC2922664886862835E6188D53C21FDC5EAF7849E078832E004CE79A7BBF122E6E59885608002C170077E98440039870E03FCB890D94001A98482EE6644097FB2BF39A93DA8811B951C6B905229A40BB97727EFAC92D266C4AAEC5623C17C1982A25D4859E362A030D191BD9E11D5CEB145E7482FFDC38ED17AAD859BE642072F55B4EDAFA4AC438B3DFB793A910BEA792780A801E70D2AF76283B60238DEE9A63011C343A586BA54CBB0C77CBBB3C8470C09F1A9C57A42436D3ECB89DC0CD711591FC674878A8317BB833D8DB10D217CC02883A1FBA2CFE3770F46721A7C9AC0045BE9F14487CE6992CC0CB1871CEADC3BA0627CFEBEB974B457D3B7953922CB0F5134918B006CAC669FB0B180BA00FEF56912B99A2C23B095E0A1F65F5611C879D4B519FB7E27153284725749C8D321178BB83C33AA9B547129E780B6C958E69192090FB3E2D69AF3B44A923276B4D5998A3349E5E291291B613B579800B12BE0805063755032A219916A5B9807A7A74A0A833F14F2F940465D970EFC7B7F8D93AE6D554A61085BE277DB5709AF4F1AE3F331B6C8900B24697978B7F69F1B3800B3606F23D90A683E44995F4A1451FA4322E03BA4E32120C5B6E6F8218B67A42D2A54467D672297B4F5CF51131180261276548F1ADD6C985415C15C3D00D83108BF34A6077EACCF7789865341B9594AC3C3781D15336696325C811842335AA43E2146B9176EA251ECCEC7F3E18C8E7F11CA7B09AF0CC14995515D80AB090711520D9BC8CD7353187BCD7D2BC4FD19911E11D904959617B4A30EA844E6292CDE42E46D2A013635C1C38C2D42BCFA68C928B6196B9EA75E6626DC7B17849205838B4C794511DED5B19CDB76CCFBC175F6B94E4E5CC5FC3C940C836C7F86BCAB3BAA860CFC3F1C8C088ABC684A243DCA306B27C2200AD1A31261B4C3C163B99E3022D8F79C9B4989AFDC32F5D93134FD57AE2A7B8381319E9FC2266F457CEE24440307417429AA259CF7DF5865A290404D73FB638BA6341316D8AA69FF605FD23453C34BC015B915D723815285FC200966C03CA84828A37579C86418D5433748669A56C447FCAF3F7A27F8BE433449CF232282A0FC0F55F6387EC0CDBAF615987A1537E35FD4ECF80F07D398BD1A4F057647C17838F8427212A33DC3D3E7052AD61DB62ECC47A3A06302A8383E1A465EDCF1BF3523A84F5549859A8CA5C0905DEBA3E", + "596D8F70598FC6837434DBC18E9891D67735460FE00248E49E07EEDCD2A36C07B37ADB63AB0DD98294B799CD8CE664D09F567A7B52C2BAC89F32366101983529D97586951B9EE52A1B48B51D87F47444D6D3A0F3F5A7063B621C6152ED5FD7A1B06903CB88D2817CC000ACD3C81A6F236CF4A268FEA9388E61EFE62FCFE21D93B8D872E31AC4C84AA8F6A66C419BD9D03EBD11A00BBB3AC07DC806A32783AADDE4B41FA8743A330CA590F5E2076F738A147999D8AA983E67E8D8CB663EEC7A693CE9E48016BDE8511484EEB22232142F6778B0AC3096F14EE5C0131C966171B3CDA96F815D8A6A4668B20F65593543B19656E3C7315523E2FBF3936D050DAFF6E260CF196A2CC83D1C5A8949D1B38E331083565E8683CFB4485D256B7E5CD128FDB516745DE86E402A67DF21FABB2B64E804225ACC7D0435D83261DB47EDC234BE5497469740C2160C793E84EB061D8612093B242D0396588333F4A3CAAE8A456F7D8F29A790CF7569530EDAA4FD2A93F9CAAE4FC4C6CD1D873153351D082B3C9FDF7C644C36D168485CB8C71E96258A3750A89BC3E4EFCB2C81130D7B2CEA9A3277F3919C193B69677DC2BD290F473DE11562974D4AD9E4CA19598E63CF0442763B1A17E00E58207FF2403FBBA79B393C885BCFADAF31AE41FD124CEBCD1AFE38A05CD7B03CE692CC4984C5EC72EEDA9ED85F8575E96CB06569B938AD6E8E78316B3FD099504D1B254D8BC1379B77D61A83D47270FEA6E2455CBAE336A2AAE8FDE479FC405D2F1AD2F54ADEC49B9C2999BA2694C42F88E8AED706DDB9CFD9E9A560FEFB52ABBEA30A09128ABC1780D8099736AF4D4F208EADEA47A1700F2D8C7765C497ED9E23E3A73EA0159F4F7BFB137ED5E6239737743323CACD84E172CD0B451D7F3232BBB6A61AA267D7F5A06A285A2FEEBB13705C824AF5E760017604AB15FB2D68E21A71198B78A6A7969012403AC2DCABED2DE26D65FC5877878EB1456F9F66DC09D66F7F66C127828E1C6E92D8BBD50D2F15AA16AAE3F38759250AF9E02EBBE9DDBEB16F7523FBD8B1473F1D2A3AC7C7FF8EBE0A5D8B764B00D190", + "0F138749C455FE4615FF58200C7D4CE24FFD8709C305C53C26AA9E340E8A73EE" ); yield return new ( MLKemAlgorithm.MLKem512, - "8D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A21791", - "FFB93E594AB462B4070F2684B3845649B96474760BED1BAAD22A38B2667B7765C504B03D65EBB1B88B613C978518428097650320821454B971C3107962E00E4A575EADA990B1B945BE845FB9411D9C8303224B7CB1D27E0286213C1AC1052C363ACA3B0C053FAF48577FE4107BF35343FC39F7A5305A98AB2CC315A84C5C60D9940E409D65B63BFB3694FA249556F87BD27C28D00A62A3299FBAC0501A3634A11267584A216F365614563FA327686CA32B38E3102E7305E48A7DE910737E688351E94DA054CF1D17944305678000BDD9CC8B93333660A85AE6B8C4612A6535E5AE8C959125141E6536AE662C741AEA0D783B53962B5CC612750AB3AEA3708445EC97B2BA1EF3589CE9F94D3A4B91E4052A746635A595568640B375E5872E30777137874A429A4741AA81CA63A90884E54527A48B84F274C0E04B92386304D50048D78713BE0A9008A69DD49CB886CB6E7BFC7CA9EA03F09896D739C292C3021B2A985CD858DE5A574A7C431CA3795CDC436EE58596B10A1507B60267B1C735BE22E05F5E6AAA12F132FB932DC815B2411CAC97EB729EBBA95D5C1CD7280A339CBC56E85D00763A1B6A371735CAA1B8A699C431EFD2182366AD4E7B4765E9A842ABAB175128AD4127BA447157F56098B3C14C561502406531FA06863C85A406494CF330E591BF58FC0216B9A66CFC39EC26C10FF97FD50017CEA705363B0BBCC9874BB2BCD0AB08631140923AA88E0AC43531757C689F3F075FEB3B59767BC1A327C1EC8A7E0670415ABAC9D0CC1D7854620E8339B5456E3D5A1AC3562E8F78808611CEEDB57BF0DAA937CC8E2C1780DAEC6FD08ACA72876EE010C290AA6136EA91E71605C6F2BEDF89B9519A5AA353C3E7415F4D4915907461C1A0559CEC7232F7A90A17821C84864739CDA43C7C94A63197DA4EC3E82DE870CCDCE4988DAB713530B8CD889A010A769DFC148CC896C2AA00AE28041B4AC0905373408082992142F61B817152609759807105C2A43C508FBB4748F094DC4A2EB6330A70543B405CC34D1842F6711B41F790E82316F6A44CB99262FC4338455863515AB67FE6898D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A217913DFA277AD62F7CAEAA930284E348256EDCCA5578A06528678CBAD23F0A8DE1D40BAD0A76BA218C111C0DBB15963741113EACF5407A795D689E6E1EF1DE8B0351", - "7F0B3336C74E01C6D3965CFAEB2FC8E3F76A7A15289E2A71E4B29F68B961786699DA603AAC6C27346E7E2DEE36D07BD4075007654FA3A38EC2885C204B4037FC247BEC1A129BC918A7EEC0BDF69DD181918875E6335D6803D882B15119C135738D636EE0A08CACF8434E968A0F4BC510FACB6A73E5F51E82A90DF199BA40C727772F3212918E7C7FE5CA720768C4E40EFFF2C341B50036EE286C6AF559026563256DDFC5E59CD4C9641B3F6B914970544128D16430AE1C0635E498818E7032C432306FDC41EE93E163867FB5FBE6FC35729FC6277D10A83ABF16190CE4450C1558FBC807F578B2CFDB10987E1CDE0D1417475D191825A4C31A65961E2C5894BE974AF20757A20D00ECA9F6CBDA704BAC3B94A1E8212D05DE26F33F26A1EA3F47E498BF0101A517F91069977425850847AE8B2D1F832C0987E8C44FBA4A57D773E85D8195CB92DE2FD8D6FCCA20EE700001295AE314C2ECF75CD90B6EDC2B0D206A00CFBB20AF2502D3FA64A1AEF7EBF982F9CF6ECEF15C83ECEAD7D0A35680E4C3984AE4A66F45910256932BAF2BC39C1DEB6F3CF1B4F96CB631AB9F2077C17EF6EC801044DB8B69AEB3DF1B983C3A473856994AEA20FFB0E004255E7A069217A44C42C8637C7EC8D921C8A37ED0C49515874ADF22650E64C569BABDAF493444FCDAF7F2CA4BF456ECB017A74F1C8BA79E1F5FC8E3F37472C4FC1AE1DCA976D418C775E029BE5C1781D4982C29AD8B4A077D05932700D821192066BC987445B164CDA9111954CA18FD4AC9E19E97A7193054D8724A8FE449997F157D4AE8F5C987F34E849EBA3A8055C945B6423C915544C4C15B9D3B7AB4698DAA792D62DEED7DD7FDDC73AC378CCBDC2479A0B7F7616405F23A9B98BAC787282A2812D0B4E27C1230FBA11D765DE5766FE51047E411DD9A47B4C762F013B90FAF727A70BEF3E4699B0991C36A0B86A071DE39AE7CCD7ACDE7C016BA396EFCB41BE92B9935FA5C6A154CA799D3D6DF188FA33DFCA6092B05F1F24B05D5890523E538F16BCAF6E64DF926BB26C06D1E2DAF5E597A0EB06F9E6357F3828F66262D530BF09C24EE", - "B532BF7A54A929B96481284CCD33558EBAAF080763A327A2F1EA81BE52A0B171" + "2F29C94A9C9351A321F262343BB7777A8B46CAB624E3F4BCB5704258B462F9EA711146AB34E748A1F08D000249FD73655CE748552909B3AA5546B54A72EA5980B957636B05EB14AA616C1B8B5AA78A5279A46B23B513132AFB85C963409E40CEFCB74F71C75298A670F7C0632C302444C7CE74F643E27B03AF93A76490374632BBFAD0C2AC84BA2BE4579C32237EC701177312B68458AF3B039F431C2658BD54041398D94F39848199C8763A2AB170C421853C7FA19C0A9ED89B665B13CE3553F6C8BA4C745327B3B10B0CABBEEC2D2C11277F359E86547D1E901F0BC44126F3242850AA7A3A00E4FB2923049205EAC160C24CA1B32280B0C0CB788857A54D223548C7505A5DCC5D29D7189595BB5CC070AA23149D376AADD75DE42A611E157C00B797735A3FEA3B59E0EC46E58A0FCB48606D033CF8D75E6592CC89448732D78B30B754F3AB7066F85C57F45E7FC035A7F08496225171373818F765FC02817BAB6FAE432CF0EC38C0779ACE7231041B8047869227DC01202419B83A7B8B87A74468036D9A2CF0C5892EE9CC85F89A32039A0D3A219D0365C600125BCC15CF607C737732D7AB5A27367ACA464571B0839DF379A79880F5B7BFF1FCC4AB69A047166800204C733B3A72FC566C2C280788CFE36A1FA9F63189B0382E683A4ED417D755A20B9895652C1E26B628BF19915D06B8320AA997531E298926F0F268C97C936B1896CC51050411338AC8088CF4A333C847384C9DC766CDB1BA531199C08B0266F1D24331E941224B2617EA9D1EAC33024939041007B5F840100B7E5437306D2A72A3B439E3D355817C78EF28332123797466A0F873A33AA76BC0B42E33C109F3EC8733785C2D03B4E64C3A5A1988C1C4947142CAE75965A610AF5D9849D6056DD9A45E8A8705C04306850B13FA295D36164F486B3440F62951F79BBA12747497C31167BE94D1A9D424373B4B377AE18299C85EE375B0312004D71C107E3ABB12CCA8AA50935ED1AA64477D866BA940C6441D44B006D22AF62960F62478BF978222DCB90E454CCD33BD9AE06F3EB34F5B576C4C9146A4514DD33258A0B6562A5EBC6A8FC1B5F15C9CDDF7EE64417FB722AE52086868BC807BF19B472AF32A", + "D01B6395019BCB1318A6670DBA709588C0A734256B3CCB44E6F2A002B91B9DFBC68E18C1957B3EE8C5464C00215E41907C7B6C1E0C20F62B294E8686627CA3181AA1377C25B5F79355B31BC0C14776621A014302DB2119F9BA4F0AD653F9B4AD562BB14760802AEC8B10348403289C9ADA8C1F39A4CBDA9648589ECFD09DE6AA0BE97AA8F0A13644F23D8E505E1076B415DC078B659E63A50D04A53E680980B2E90241435AA0810CC76016F0010E7CF8B2A9A0B1F0A75CC068CAFB4A5AFCD74CBADA6456D83A4D460D978025A89B379F2294D61BBF0A344611635335CC05DD24BC800C48845930F90538C5854D9862B059F952A25B3D2D6BB3E70141EEA769BDB31F42467C16E6509DF8A0A24477916A28B623A555E47079C61EB7B7A5431085AE7457F696812CC49D0DB242FB42B3A58A6B405289974BC34DF24C8E09C63BB81F109468B112668CBB408AA13AA1F2B4EB79A419ACC2B3C05807679E8EC60951B266D621319EBC289F8709E903478D150448FB00B142BEAC93BADAB7703D5CC4ECD78A05121B4182501CE62E4A3BBA65CA6C57156622CB624F844172B0CD3B376E1E008A25E0A8BF982927E154C55A82EC276DA312C2721570F835C51C131E7A011D26F52A90E5BAB0B813EA41C7BB3BC7FAC789775286B1D115CBB865BF96324FA99A3180B7D1A8B7C2B539411302EA62020611359659C2AE0062B1C52C83B7B94A831EC9036A79025689A70C14C44BF590A914A3325392827F6820B96961E7CB2E88B56A1F706C6027A18BD3AB8998124D8C73251A8CCAB2771A630BA448318562061755B6F271063100C4DF788030113F5A8768EEAC11B31A1F0A81C5D14002242409F35B2725AA68FC4087A22321F122B672E101052C3EE59571A9B71C17976C3220C070C0A4641B73B007CD51A5561BF0AC24B58A1DE1443EB38B794822C4148843746C44E6458FC92F1BF4289E3178CBA74521D792DD297D93D15FED878F9021B8F1DAB90D6259C354CC9B4A383A58800C42547F9A13A4F809F5C05EED58C6C98A878FF432ADBAAE218A9C283CBF45D527ECF8A4B867ACD7576957D1C12F29C94A9C9351A321F262343BB7777A8B46CAB624E3F4BCB5704258B462F9EA711146AB34E748A1F08D000249FD73655CE748552909B3AA5546B54A72EA5980B957636B05EB14AA616C1B8B5AA78A5279A46B23B513132AFB85C963409E40CEFCB74F71C75298A670F7C0632C302444C7CE74F643E27B03AF93A76490374632BBFAD0C2AC84BA2BE4579C32237EC701177312B68458AF3B039F431C2658BD54041398D94F39848199C8763A2AB170C421853C7FA19C0A9ED89B665B13CE3553F6C8BA4C745327B3B10B0CABBEEC2D2C11277F359E86547D1E901F0BC44126F3242850AA7A3A00E4FB2923049205EAC160C24CA1B32280B0C0CB788857A54D223548C7505A5DCC5D29D7189595BB5CC070AA23149D376AADD75DE42A611E157C00B797735A3FEA3B59E0EC46E58A0FCB48606D033CF8D75E6592CC89448732D78B30B754F3AB7066F85C57F45E7FC035A7F08496225171373818F765FC02817BAB6FAE432CF0EC38C0779ACE7231041B8047869227DC01202419B83A7B8B87A74468036D9A2CF0C5892EE9CC85F89A32039A0D3A219D0365C600125BCC15CF607C737732D7AB5A27367ACA464571B0839DF379A79880F5B7BFF1FCC4AB69A047166800204C733B3A72FC566C2C280788CFE36A1FA9F63189B0382E683A4ED417D755A20B9895652C1E26B628BF19915D06B8320AA997531E298926F0F268C97C936B1896CC51050411338AC8088CF4A333C847384C9DC766CDB1BA531199C08B0266F1D24331E941224B2617EA9D1EAC33024939041007B5F840100B7E5437306D2A72A3B439E3D355817C78EF28332123797466A0F873A33AA76BC0B42E33C109F3EC8733785C2D03B4E64C3A5A1988C1C4947142CAE75965A610AF5D9849D6056DD9A45E8A8705C04306850B13FA295D36164F486B3440F62951F79BBA12747497C31167BE94D1A9D424373B4B377AE18299C85EE375B0312004D71C107E3ABB12CCA8AA50935ED1AA64477D866BA940C6441D44B006D22AF62960F62478BF978222DCB90E454CCD33BD9AE06F3EB34F5B576C4C9146A4514DD33258A0B6562A5EBC6A8FC1B5F15C9CDDF7EE64417FB722AE52086868BC807BF19B472AF32AE511FAA0E231976722B8C8DA3A15116AB0407F3C7209D421D97969800A933F9742B5A904C6C1477F268EDD8106D88618B002F3A2D0FBB72682CD37B51F9BEC47", + "3856C757D2A5FCCD231A1669ECE3832AF80E5AE832F3B1314ABFF54CDBB94ECBE156D3E93FC4705C46D0E662468EFFBB514DEAA24C384DF4F0BB2B3442D6C67926B5D4EBC6DE170AE0A420EF7319F3A52B6F7726CD47F743B86CB5AE06610FE485932D9B6EA9CDE8023A978DBD0DB5C5DD30AEC898A042C825F0143A32DE320EA97CC36B1625D652342F716F61446EE2355435A9FC043DCD68C6BA0C15AF81A50EE394CFAF9558C6247A6E83826FB48ACAA574F26FF137676348EF1FD80EACE7A20EF6A5150CA1F094A9C31794E3C20CE6CFA71AAC394072432CB4442C6BC7D9AACDF493949CB4E9F33B1946ACFAB8ED5C7D978E43DF907848996F9CDF2CEAEDCF4CFFDA1F18AB30EE1F68F505B4C3A1CCFAF492944506101FD2432667B4D1DBA381C3401BCEB2FCD93CEE7D506E63D97081D4721A453BB96009CD58122AA3B2BADC079EC0358C6C8051D58DBBAE2DB9EA7A28668A2B2FB35D90A542212C7ED4C149416B5CA79B9CCA8B608062A0F3E8E6801D86C8295BD1BA1A078935ACEF1C9DC52F126E83B79927A361167C4DA101FE8C42C20E3AD167D28A73E22093E12EABC39A1C0B3A295C3049104E1E9772D3A4A76D829D9BAB22958C14C301488287936EADE7FCBF43744E71B35A23DF0BD07D2D89C468CE3F8E1BE589B202D74B2D4DECC09FB919EFEA56166CF385C40E113FFFC570178044ABADE35172614DEDF9FA93D91AD8218655C8519D5871986C16320D845D5A5231DC1E04335A26AAD213341A5946680FE9F22CC7BBEB660EEEC1CE9BBC92D497A9ACB21642F9CB52D19AC26B774FCF8817350E301E77CD294ADDA779672597BAD395F4913A45E0346A41C14C0A473928F89B92A7075B63E7929E1FD45077D0401356705DD9B6B75D5044605017A9139B19559DB18C3B931DD71A532C861AF40D18D15C63531F1545D337BA1A30841CDA6AB7D6EAFAA4798E4E6980F7718EAE92775DD8460569B05440DCE3789E6D743E695B5B1BAB0C9DE9C666C1595BBEDF69E80445DD53DBAEBEA126E45479CD6472D5F97840475EB1E52F7984ED651C07B82D584A07D9099C353DDA", + "ACB0CD384DA7C8A0E5187025297286AD154E9E37448D9D0E798BAE24FA7A6727" ); yield return new ( MLKemAlgorithm.MLKem512, - "8D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A21791", - "FFB93E594AB462B4070F2684B3845649B96474760BED1BAAD22A38B2667B7765C504B03D65EBB1B88B613C978518428097650320821454B971C3107962E00E4A575EADA990B1B945BE845FB9411D9C8303224B7CB1D27E0286213C1AC1052C363ACA3B0C053FAF48577FE4107BF35343FC39F7A5305A98AB2CC315A84C5C60D9940E409D65B63BFB3694FA249556F87BD27C28D00A62A3299FBAC0501A3634A11267584A216F365614563FA327686CA32B38E3102E7305E48A7DE910737E688351E94DA054CF1D17944305678000BDD9CC8B93333660A85AE6B8C4612A6535E5AE8C959125141E6536AE662C741AEA0D783B53962B5CC612750AB3AEA3708445EC97B2BA1EF3589CE9F94D3A4B91E4052A746635A595568640B375E5872E30777137874A429A4741AA81CA63A90884E54527A48B84F274C0E04B92386304D50048D78713BE0A9008A69DD49CB886CB6E7BFC7CA9EA03F09896D739C292C3021B2A985CD858DE5A574A7C431CA3795CDC436EE58596B10A1507B60267B1C735BE22E05F5E6AAA12F132FB932DC815B2411CAC97EB729EBBA95D5C1CD7280A339CBC56E85D00763A1B6A371735CAA1B8A699C431EFD2182366AD4E7B4765E9A842ABAB175128AD4127BA447157F56098B3C14C561502406531FA06863C85A406494CF330E591BF58FC0216B9A66CFC39EC26C10FF97FD50017CEA705363B0BBCC9874BB2BCD0AB08631140923AA88E0AC43531757C689F3F075FEB3B59767BC1A327C1EC8A7E0670415ABAC9D0CC1D7854620E8339B5456E3D5A1AC3562E8F78808611CEEDB57BF0DAA937CC8E2C1780DAEC6FD08ACA72876EE010C290AA6136EA91E71605C6F2BEDF89B9519A5AA353C3E7415F4D4915907461C1A0559CEC7232F7A90A17821C84864739CDA43C7C94A63197DA4EC3E82DE870CCDCE4988DAB713530B8CD889A010A769DFC148CC896C2AA00AE28041B4AC0905373408082992142F61B817152609759807105C2A43C508FBB4748F094DC4A2EB6330A70543B405CC34D1842F6711B41F790E82316F6A44CB99262FC4338455863515AB67FE6898D895727F11672FB1A064C7A1F53AAE3AABC55296A44C3758BACC25866A78F587B6804548EABB93F70A931E0576B3584A075BBEC98C14BE62846E579F01542C5125E29BBC449E4BE2A14BBF879192FFC272B0977876895F610B2E5C4236533240D07CBBE67412E8C7B3A143542F94B73BB776EDB8F079136AF08883E30411A6AB3415340698837C9F6B314A206E2A7906275BA04DC442DE87D00D57C6A35B2CEABB4C0CA9366B6897FF03D2B212169EC7555FCC462C568C9E3346203A9AA5064A2F4ABF97115E5E2C77AD9101D5502554A26E5366FEE2177E33055956224CF522B2FEBCBEF3C4631354077153ED996C9D8D2961153C373D66C3889087D7BCE35378DA5F32EE806A3D525C6A243176BE5856B687299A56331CC4C448AA07C23BD937C0FDB96C118485B17250A9BCC464B8046A57C8D1DAB3DF5D751C8C2B2999A3BD4F134DA7740D4948EF0A796C5EB0BD2D6CE75B853CBA17EA1F2B1DD2025C6752FEFFA324D463F722898821A537B78812F52921622111EE26E69450D5934238A6A5BE752169BEA78348A4C22434EEAB726D9E126BCF8951915428CD18CD771426B3A984E50B4D7F303392607C217120751942C4CBFE07A21862C9B0165565A487DD0E72EFED935EC99360933923AF601C097BB99312EC8F213F5D53D56687E89FA1E3E9219341A62953631551A568115CD56A20E1B088900CC286125AE8B450F8428269D943C2354278B184DC135BF79345A39601D33FB901B97467D950E981644E2C500885A7D9B3243AC3463D755A57F2A659108244A070DE13154F83A06CF4928741568505965E1E06D6501540DC8972FDC951A862C6A35CCED9245D1B2B85933550D96B60FBA9FBAC34888E87B6B335BE41AAA72447FD5D9A64E529CD29A365B6603ECF9736429B02FE46FBAE82EBC8003E127508BA518303382655C51551CBA7F0A48C4E58D1052C6A1648509E308A3F95814D7138DD28ACE9306AA0529A9712BB6827AAFAA6CAB67CAD96CAD4FF4903CA02954D26132551961C0B680000F01DC08CC361BC9FB449D455793CB2659D800016C87A1B98433CA191CC663BDD64304BEBAD0D3333C2036619F936ACE5A0B62805EA5FB49D9AD8106A217913DFA277AD62F7CAEAA930284E348256EDCCA5578A06528678CBAD23F0A8DE1D40BAD0A76BA218C111C0DBB15963741113EACF5407A795D689E6E1EF1DE8B0351", - "35F0EFC059699AD0E32C2B349A262661CEBE7DC3AFDAE847B3F30ABC14638B9EB3072F850CC0B7F71672441C12D27A355955CACFAA404C18A2550872CD6458CAFECC77B77E403F05F1E52585D4EF03B3918585C1FA53A154CC120457CE3A2A9DC472F160AE5840222A301F44D5E34B671D664E10FC71108F1A3934704432C00F4E1C244882938FEA598C64BC12234961A92357F4237C3EEE9517C50B4998049345B28D28E434EB47386185439A39C9E8D1BC0265276DA6C2DE621A45D2BCE109612785913DF508198A88171DFC4582BCDFCE3232EFE2D22633AF0EE70A198B72EC0F7D5ECECDEEBEB678273F459079E810BF95D1510FACE9C27A352AFC513EA369A770E49ECA43C286B460FECE7B0DFEFE74F32FBD0BEFCA954130A15DBFC4E714DE083E38FEA4FB7BAB28FF7034A97C6B50F0BD77C76B039302D5A0376022A7D3952E290054AAB9DBB9E196874BE23E9FD7B9708AABF38B22B41024D37AF2C6C38ED12B4196ED79B99CF36244A84F7AB94111016127837CC21842C1AB14781D318519E4C05CA5BAAF7A7332AE26AD67F6298A295046C432D52785A768C4FDEF981974C299A19CAEC9AB1ACEF3B911A3653EF5DA6D9D15F0799A7F08CCE77629BA818341037EDAE829DEDB6B905A484A5916AC78AD0654B506950DE6FEE550056AABC63764F996FCFF57A66B44153AA02613D74003ED5AD2216BA38B951D21FBAE7CBB5C422559DF6CCE9B8F38F2BE909D55851E4CE80A97E5FB83FAF63016B810755507A88297FEDF0450E13EB961B26F1BB6C885BF39DADA5652FCF227645A74C44AF060F2B219D60B2BC536732CB6471138EFC377EE6421B529FAFE5E49F44B69376E49429132F21313F6706D7F7030BD7049F199798F78B727895AAAB38B9FCDC7AA70D80475A9A40ED9F4023DB1ADD41DC406333238C7C81361A0F704B0F9C295416F6F06CDA2154A531424A51D5C24EACDB51F21C96A0183C4FB177FF4BFC48DDAB3783EC041E920829C97B3A37DA7B7F3C78D29A46762882665203761AC906E9FBC1E788FA5803F05F9E16642372DC463E79DF833C72C510844EA3BB5", - "707365FDAD892AD8725A50D5DBCE635DC80F6D4D6B5FF28CEE1FE361C067BB32" + "21E3A32F34C0D26933A251CF7AC2C8588903E4E8AAB2956AED328687D59F3B0179B0F008B9D82E30D62F979891E077661FB02540535B65B8038EF647AA977B7EC28E737351D871A128D939162A8B06B596CCB112C9477134D00FABEC425C063FDAB7092940A02D56B677C7B5C6791352871B72B8B7D1539525A46A05318D1451BDD8445D93C7A42108109417052BC6CB108896AE0837EF0337AD349ED682578CD083BA7125EE909BF59ABD2515875494AB1D25A2164CBD6B346A8E057AAD77C3A524086801CE61772197B7AD01D18B12834ECF18394F689A74CA4192A86D68F112300CAB592B2C0D2488C2C55392DC4FDAE417AF076FD068424F16CDFBD36588E4AA96955D6061960ABA9BF9C588AEB2203F3083D9B101AFE366B26AC896D78951726B4143AB39725CAB14CDFAC93A4FB2BABAD835DF36118C00002E2634D954A871264876B8B46549367EE14EFD78037DCA255AD5463C83A5623544144699F92420B5891DE80280B7590E556AA87EEC3AD010261852A3F437C7B40455E09BCD9C514126281EA31B43DDD3C2E1D67A845A87B3A38E7DC41BE5C32C28F2C4D5F17D839773730717377AB992710362CA38652C31B034532A1C393933A11A8B4D6BC17A35B9B0B9A4621170B0106134C045947651A121E3455A79720CFCAB6A725823503442F068C9F5019FA1A69C763B07A66FB30B45F95B796B802E09718381D96C28D487A69C55FA602E48823F8F49A9ED69234A341D399403623C65C4507AA83A33AB10B1830B93F270574EE6146BF75A82731B8A8B83C823C514969623004CF4ABA8AE086F949926174B40EBB0CC6EBA9382D61F2FD01BCAC78E80EB1136386B9DB54003964134873C5A8870015C0AFC364CFBB52429243AB82242E1F990E6E285A20C3352374BE0035124702EDE831314DA724900BE6A86811FA7A488F6695D4808DD0081D0648D2551355952B31447721E915ACB93AB8AA4B394130EDDE1C63E9B4440B21E5BA572D4321A69525A698865BE90B983F0118DF62769C78521049DBF2B2953F3631DA706114A7641DC11D95004D827BC8548A720A2B05F0757A1858E6FA5EF180041D7A2F738F02464C7B7408302EC5C501E0226552EE6DB83", + "51A822E5747B76120A780B2F0476232B7B6A621C7256D001C1143569A2ACED1B5C1D43B171C49AA4D0423885BA985738CA8710F2AB9463410D18D936B064443C1C7535BB08C00A2CBEF22E5995224084CCE04460950C3252D948A732B52F8A174A70C35C829223E9854415212F724A481882A7368197BB0DA8560C6A92C455022145EA0DD7292194E35371BA31F9C234A8D9AE62FC2D004D4CA4A5A5E82C892094BB5E27BB749C8AB4AB655E175D0090319CB620EF5BA883F66DAB93789C74C8AB820000CC472D57A33BB98D0467CC0DF7153D2C44E490111AC4C97900AEFE9B7CACE43BCFE622E08AB7CB567BE17A98083934CD134738585547583CBF2281C2D37F2BB34F7878B91AC4629060AA0C1B7E1F891B166310035625254893FAD88CAE845049EA95C8910F6039A91A31ACFE006ECE2466D0F989B89297FDD65066DC31DFAA6A43091316581A60B68F04E347784C2B3BB1723E9B6C8C9C74907421F6D0A98E936432086E51A5708AD237DB0247D48B724AD44834628DA4781803584242D8871248C26058A20E855BA2793D8AAAB743F065ECD84D529531D64A775B62A4FDA65DF4FA7E02D91E85036D8F328B002DA02D1823DDA830550578B5CC0B04B3CF5BA48C3FA46BC5D8126932890A690925A66423E793B5AAAEAB58690963B08B10A7A892CC6AE094CB27704ED1C673EC4845715FF9639375E92BDAA4BE12517AACC3B9441971FA0038371297799B99CAD9C0E303BE39938CED9BB1F23CB9B77928351636B961280C626CF512477E1046C907C13D214172E0986ED0C20B70A9CE03181F00A886B5CC72E09ED70B95E0CA154D3498795485A4319D02459DDEB7B08F38C3B3A545B11A59217283DF46219F722641759D7C8565F163C27EBC61114434B5472C1F66929843BAF2765DC328614CCC6EAAAB558A0AAB5F6A3CAAC17789E523B7BA389DF92D465C403290A626620A819C1AF3528DA871612EBC1E1FDA68AA312E13934F36CB42F6353F798481B77762BB9600EAD4825D2110046522B5CC1894982E5A254AD6F97BDF186060284A6425AB1DA53756296892A1733CB95521E3A32F34C0D26933A251CF7AC2C8588903E4E8AAB2956AED328687D59F3B0179B0F008B9D82E30D62F979891E077661FB02540535B65B8038EF647AA977B7EC28E737351D871A128D939162A8B06B596CCB112C9477134D00FABEC425C063FDAB7092940A02D56B677C7B5C6791352871B72B8B7D1539525A46A05318D1451BDD8445D93C7A42108109417052BC6CB108896AE0837EF0337AD349ED682578CD083BA7125EE909BF59ABD2515875494AB1D25A2164CBD6B346A8E057AAD77C3A524086801CE61772197B7AD01D18B12834ECF18394F689A74CA4192A86D68F112300CAB592B2C0D2488C2C55392DC4FDAE417AF076FD068424F16CDFBD36588E4AA96955D6061960ABA9BF9C588AEB2203F3083D9B101AFE366B26AC896D78951726B4143AB39725CAB14CDFAC93A4FB2BABAD835DF36118C00002E2634D954A871264876B8B46549367EE14EFD78037DCA255AD5463C83A5623544144699F92420B5891DE80280B7590E556AA87EEC3AD010261852A3F437C7B40455E09BCD9C514126281EA31B43DDD3C2E1D67A845A87B3A38E7DC41BE5C32C28F2C4D5F17D839773730717377AB992710362CA38652C31B034532A1C393933A11A8B4D6BC17A35B9B0B9A4621170B0106134C045947651A121E3455A79720CFCAB6A725823503442F068C9F5019FA1A69C763B07A66FB30B45F95B796B802E09718381D96C28D487A69C55FA602E48823F8F49A9ED69234A341D399403623C65C4507AA83A33AB10B1830B93F270574EE6146BF75A82731B8A8B83C823C514969623004CF4ABA8AE086F949926174B40EBB0CC6EBA9382D61F2FD01BCAC78E80EB1136386B9DB54003964134873C5A8870015C0AFC364CFBB52429243AB82242E1F990E6E285A20C3352374BE0035124702EDE831314DA724900BE6A86811FA7A488F6695D4808DD0081D0648D2551355952B31447721E915ACB93AB8AA4B394130EDDE1C63E9B4440B21E5BA572D4321A69525A698865BE90B983F0118DF62769C78521049DBF2B2953F3631DA706114A7641DC11D95004D827BC8548A720A2B05F0757A1858E6FA5EF180041D7A2F738F02464C7B7408302EC5C501E0226552EE6DB8368E20D6B8B724847EE33153F8A80C0C1E6C1EF48CC62258A9C317F45CEFE99731D01927CE0920C048F5700432F3C5C7EF9AEAFF97BCDDBCCB14C362C701F896F", + "768C849DD542135E428DA8406B93A10BB55C8A062A1E500E8B902FD6275557F3E29395112F7581F7826333A4FFD3D49F660B8AAA4CE0DD38006671BF3877383F8056684A3C64B356029122643ECA9BAFD86CF4F82A609588A4ECF8AAE1B541089FB6FB147E7C54E58EB9CA8809F1702729DCDE7628C948BCB4855E55D425893DF2815A016832FFBFDE9C0DE95B2B0E2720E331FF9F92474213501D2B8D80002ABA34609C08B5B0681B1D2668783005E75BF224939B24FC5F5AE399FCC19B9688C06F1FB98E4A78A5C41CD14F5023992CA8EAD1B83BBCB49FA51E1B269495F5D5FB4A6692319FF09AE80C0FBF959B77624A1753729B0760F0BFF8C7B12922E7872B3EAD813E68251014CE38C983EA6FDB01BBF6CE94343966467A56495E61A2F793BE805AA54544D6447A7310645311FC1A8233E3EC1228F4741182055A58162D381912CC5F7DA0E544EC448414E8AF3F45937EAC1646DFE90B13D5A8E50B25F692526B886F41E40A74B9D139B64A53AD73987B0B7105792C8E17CA5F4C8F46C976B7069C4BDD1F97B41F7CD4A97903882FD137B406EA0E1DBE67BF21F6437893948BFEA806A390237F59D573C78FA0472497B1B0A2E343AD0ADD3DAEA44A655EC1096A77BF7FD422BE04E56BEB8E41403011FE6B92C848283933D68E444EF6E547D568B858F108F17C3EFBF71102ED89E4F3335A5C76951C60325389C37A972D2325DA3A048203DA2CB7E2929C548007B8A9C68517AF654FDC851DA9DD2EE53993795E48095935BC6601CA47BA8FD3B06B63559E10CB42BF1C4499CC9B8F13B93639478A5C424F607B0EDCD1AE0A2FB2FA77B923B1DA1793A2F71EC55FD58F4615D73D86F385FC5D96B19F1A53A8C5158E286DAE4D1A1EB82A0044AD4C5D051F94A0609E97312E83B0AE7D2830D3C3E12E939DE17BBF3AA7B455994A85B2578BB73E611A53A805641DDF9567C65432194C03D7A362E9052E932287DF0BE93F48DC7FAA6ED702D8960D6B6A71421FA676B15452E3C897D06A33A0CD049B0901C5613385D889857499BC873353BE56FE55E4F31F010B2F251ADF948F97A754E994", + "AEDEB99B87C330FE324A79E9AB6814AF48E6B028136A0464B15350FD91220A8A" + ); + yield return new + ( + MLKemAlgorithm.MLKem512, + "54F533124924D97239405178EF508707A7B735513873A50AFA0649A54C1EB96A7A8A1A5952727304F7A2A5F8690AABBABE4A5C2C02389CA299F23B655A038C24585E8916C3B126021C137D4F9C823DF346650B940DD956047650C5D606E7827C1001355A3087D4B28D3D8B6BF9B508DEBB8F59F517322107EBF89B23536450F13AD54A169A643A2BD72D701407DA1777F26B71FD0376540BAF962705127C30C6D28FA584A1B07158E04B0C5A603776D6AC77F99435EC17F55803208BB0CE30B998A615F2D4669BDA329208A35174A04B91A28330385D609F22185DF20CBAB9C520EC9279B41207D8263A8DF366989216B0971243ECA22245C60197471EBCCD96B73E4308B8C9E37203D15D228395423BA3EB63756536B913F4B5637C6A566C1A2D96B94960B5ED85CAA9CA099B6264BE515A46B85D7E3216B9F97AD917AD3FB59422B093B4160C2BCA5AAB1B8A6B02C523E574648588F511CB5698342144472A968250F9995AFAA655DA57A13A9B95F8376F05A336D6A58B388DBE8052C4C3BEBB4BA8937211DF961DB1921203497200243231F09D88CB9130BA1E2D561EF9F266A4C18AB7497E1DF1266BE6583A4089DC1C8AD97081E1A95DC5D4141184CB7A5491954105F8F42E23E59618669040F569D9B1105D027DD054A810CCBE1D392B06209A1219B775C10A6A5B43F8444A7C217181DC3915811DC5C2C7E059182E39A8FA4635F3867BF962479F71A705011D3862A038C0AEE9F2540F34C91B61BBAE1CC4E0B714EECB39F3E88049D9180A542F830C0855722B4ADC1185A037976C298E945120FA2E9D440F1F0AA783D67EF53AAB4311552387A9AA2A2BDA892FDF6A1EF8CC11E8674D765B9359B15CAEC31205E502FE2A446968A397DB273E6C3A9F9C9CD5F0C90478597DFB3451D0389B307028B057BADCB6751C5FAF4A9AAB94850AB720BF9112A8D40DA0F30BF094BA85842BA313BB1670C2EB157198566DF4435415FC681F9ABC7B0189A08B771836BCB76B8280D191D9F080F391A0928C21B9993333AA3C67E9C2E412942A204186A124BB016B27359FF64378BA944818084EC2A764C79EBF4243683A2B216661BF242E56F8F2295399B0A1B0149FAD31AE40", + "B86B90057B5871C81C77E4554A5BAE897377AFA99A49EB94D0EC723E526B5815BD73E1BF4DA14A6ED130D8A6CF55809B348CCF94E2A6B0A8CB84E046EE72C23DB47BF3566848813065BC2C91C99A47A67E0837A842C94296428A396CC556E1446D7C58B76B831B65B63D9749997A08DD0897DFA8B36923C366431353213CC4C18D3B963FF0637323169B64D5B22818405753B5E5A12C15346E8D554D0509BE3F2C4CC06262009451BB3B5B9FF45D2EB84A6402BC75395AE93338D33B6BAFC301C424CB1FABAC82C08192B0A4615288E2F8364C79B83663CEB609AE2A7559343C48B3A95574A3638B8C1AA5E4134885CA881775437A05AB25943EA75D3BFAA2EC993C74574365761BF409C15EA64833720EDE1146DEC322FFEC5186BA71392AAC3454C93C5526D204B199108CC1E321AF3833244C8FC0C8CA802CA31E1A587848BE1247B260186F5F7127416B950DCA863AFC89109A379E863A8673BC5FCB632834C99766CAFF332B9781C6FF65BFC2581A3816295628846D926396EAC04A667A58580B4CB416D13500CDF48B983054BFE49063C3B202AC40AD79319CE606BA7901A6A684145CB944E71FD0D2084AE300EA45BBFE6C5B862A07F85BCE378418388365D119B9D8904A10B7C2D19192D24AB3511233B3AC2B32E011D959BB4F8C73D6CAA12AFB869D0571696609966BB5346C0888C6B0A2288591E6B5C5E7828C26AAB3726DE9E17088F10A9433997C498CA383270321CDFC047305240321B8ACCED733BFF52740147E58E516A10A89F518C0EEF87B57C32472D3ABEA4AA5435C5F97D73936D5A8A868865E53221C703751BB616CB73CED8668AAC5053D06BF277602B90C4DEB643C556A80A3400458901BE121598339BD9AB65C732C1A98FB66DB81A29DBC345A4B8F5A672A7047B8C98062B4C025AC3526D0C3416C91A7C4A6A231D8687E9880110308705183DDCB9352C1B7F3C98FF0082C01F1BD71552A1E7A6C0A77B40AC603B27BB8020A668773583E9C2048BA337E4A2200C2049FDA2AEA23260E2272FA541D93AA43E022BACDC618F022397300C3050CBBD393530886B554F533124924D97239405178EF508707A7B735513873A50AFA0649A54C1EB96A7A8A1A5952727304F7A2A5F8690AABBABE4A5C2C02389CA299F23B655A038C24585E8916C3B126021C137D4F9C823DF346650B940DD956047650C5D606E7827C1001355A3087D4B28D3D8B6BF9B508DEBB8F59F517322107EBF89B23536450F13AD54A169A643A2BD72D701407DA1777F26B71FD0376540BAF962705127C30C6D28FA584A1B07158E04B0C5A603776D6AC77F99435EC17F55803208BB0CE30B998A615F2D4669BDA329208A35174A04B91A28330385D609F22185DF20CBAB9C520EC9279B41207D8263A8DF366989216B0971243ECA22245C60197471EBCCD96B73E4308B8C9E37203D15D228395423BA3EB63756536B913F4B5637C6A566C1A2D96B94960B5ED85CAA9CA099B6264BE515A46B85D7E3216B9F97AD917AD3FB59422B093B4160C2BCA5AAB1B8A6B02C523E574648588F511CB5698342144472A968250F9995AFAA655DA57A13A9B95F8376F05A336D6A58B388DBE8052C4C3BEBB4BA8937211DF961DB1921203497200243231F09D88CB9130BA1E2D561EF9F266A4C18AB7497E1DF1266BE6583A4089DC1C8AD97081E1A95DC5D4141184CB7A5491954105F8F42E23E59618669040F569D9B1105D027DD054A810CCBE1D392B06209A1219B775C10A6A5B43F8444A7C217181DC3915811DC5C2C7E059182E39A8FA4635F3867BF962479F71A705011D3862A038C0AEE9F2540F34C91B61BBAE1CC4E0B714EECB39F3E88049D9180A542F830C0855722B4ADC1185A037976C298E945120FA2E9D440F1F0AA783D67EF53AAB4311552387A9AA2A2BDA892FDF6A1EF8CC11E8674D765B9359B15CAEC31205E502FE2A446968A397DB273E6C3A9F9C9CD5F0C90478597DFB3451D0389B307028B057BADCB6751C5FAF4A9AAB94850AB720BF9112A8D40DA0F30BF094BA85842BA313BB1670C2EB157198566DF4435415FC681F9ABC7B0189A08B771836BCB76B8280D191D9F080F391A0928C21B9993333AA3C67E9C2E412942A204186A124BB016B27359FF64378BA944818084EC2A764C79EBF4243683A2B216661BF242E56F8F2295399B0A1B0149FAD31AE408EE623755E05379EFC338DF128DC1EFDD786FFA4450DE832547AF7A83836D8C7692E3C7B26B9695F3A7AF331C70E24D80142D4BBC6A941FE4DB07ED38E7B6006", + "659D3ECEC912EA365B95A68E368FCAD3A2CE9E5B6032687651ECD4DD8A32840559CF71364852EEC28540E55674690C540507A3781BAFA7BFD7207D4039F3C02A612BA8EC09CE4921E180DAE0F9603959AC2D578958E61F1C46A4C19DFF316FD1DCDE63D29811B4A60136E015208F322B487A47325707A38F4D11863252A9A4C82B94198FB56A4356CAB954CD4C4685514CA69ABB61D9DF45540D194DD8B673300E13C55455207129742E8B1E9667290590F7272B984B489D2F2DB671DD02FB1F499F47A40DBDF33DB8107794FB68522A5F979762E9BA687882E2C4D5AAB3B83CC513518AFC6A9418B1B435FBC18DB182A6A9674AAF9C683C2B2450892A142DD3C2C1391F77F8A57DC79510973FB5654F379BC7F3C37C6A5B203C4172D110A9975D71A5873736A44033F67B007B571A970EAF8369327B50CFEE57A2815AAD5DEAD72A65522D4815EB5BFE72B033160B0CBDE31930A5DB1506CA17F91F0168D64246072D2A5A3042E3D0BD3C625F798C40502CF528A6763EB25800832719682631E3D4A000C511CCD99D3E3C905CEF5004791617D13586B74BE7830652F363A8146B6888DB5E78704319F3A8A0B8BD8209023E22D5C4628ACE2982A20AE1001AD5A6363FC3B34F42B91558A18754FDE4CD4A3858D37341AB956626D8667E139022347171B01AAE07639E0E1C8E32EED8F9CE6D030E8740F907BF73C25A2BA8E9654FDA35D26E3832545832A58E2838EFD798283C1F719D89426D8FBBFC440D8C29DBEFC315B5BA1592139660A5DC2B4CCE72A9A03B3007B0DAFF89389C6620800635EA00DB108AD9D25A94B13A05732E591C140121B636C5D1821E8D4E5139708670F8BBBECFCFF023C0950060730D0BA0D893168A8EAE3629507D8C587373745A22DEE52F670445EA770FF27C857914DCE69C7B57FE9C8964830B39644B5E485A538F0289A7D364CF80296CB36DD23893F6D29B04B0EC0F04F6758A5521C3E5FA03D0F415E53C5D94466B2C655605B2DDCF1286DBF6360A4F6D8FF6AD4031F04E8A46632149D1CA458DA6453AD3DD09069A1ADFE61DE1F8B86B24F45414B16759", + "D2354A942E97CFF7B5F79E6DAC7A9B178E61F889241228B94AAB2529ADEA11A1" + ); + yield return new + ( + MLKemAlgorithm.MLKem512, + "62623E4E59A01A27B1526C594A0894863610F757151C847410A5AF63E95D91B925CA1791EA788171A4940BE89E5F6A50D554ABB33282F057AA1630359B80AFC958B54C612902618197B6CDFA0C6720F36E070824AD372C499895985111C756739AA8ADD2C21940920E4D3379362A16BDB20E22A6BB26B079845BCDF32A20646B480D6C9ECB871CAF0A38F98662D3A9C89E8ACC78842F9C2C76AA79840E5491AF6428409271E6349CAB281692127B3985C547C009DA497D4F4424DD8109D52A476D440E457762C664683E8364C26C0EBBC827B7967207690C8AF5BA38F4215D71652146434A2B42CD61804D77BC61BAAD539124AB6B414341A8677A8DF0A9666E26BFB3300204194E24F350BEE636575C069272BB6FBB34A5433D6024BA6643B02625C41F055FC049BAE48A7D754681829A852C802F53D34E6BECA36852CF62C02D3D4A9D92A1856195A0C6F6727EC3291FC8CFEF7BA3838496FBF89815B32CB55C4DDF075322377AFFE4C1C6739130015D53E9272CE826C63252F032059286391164B950F921BFF53ECF5767F0B6A5A2C2724FD47F378261D5324380646237355276A0291A0A085389C210F5A5A9380322D2BD8C97ACA6DA7C326A8F765C054BE323395AB9383B7847C741E6EB1FA52C5E78D3856ADA3F19DB9C5AB914A71A88FC049445C3241050BB65FBAFA969C1B5E47C3E988D9CB022836780313A0BD728AB51627FB8D478E2C62163F996E14A0CD52859FE32B015129EC6581742A6C48B95953E70CCB73299CE847ACA77609789AB6496023491838CC9C0B321CFA8DC29655A86ADF8A149BC390959776534726134016C9B1B562C2EAFFCA6C9A53546FC7DA2C222E9545AE6C79167706073C0BF41CA0A8FF18C2ED1C4955A282A79C57E71097E67CB8A930ECEE0037E4BA749FBAC51B06890736CDD86184A08528C308ED659477BB721AF5CAD9D7477D9EA7FDBDC558CD455EF4B07AC746648A384794AA1BE7B22B9A507B1DB6A6DA96CC6146471F22F55D7C0FCC106BE7C5B30E634E381873188A46561981CB972B981C51CF3C49B2961B795AE260CAA1AE67D03717EC3A23819F5FE2CFFEA19119C220C5832EB7FAFBF2279D277A8A7D1030FD1F358", + "3B51977CF371CBB75DA68C26934237638C1F28CA097F1AAF8A387E669041DCB329DB043F416B64F6EA35CF0A955463459709C75FD349FF3B87D0218F6600812E3B9C08446D471905C26B2D512BBEBA55229CD6558561655B2C7480582A54EC8E404796FC8B508CA58F048235B0E91F9F682E22FA1BFF713266B2CDE79AB271E8824FAA25C1589DE2A07F2BA81031164388A16C10A4786E50199AC023C3A30DF26489DE288A715141299BB9EB0CAF78202392B01FF482754468AF6DE863A708465247093D201231307A455573BDDC356F206B065492EF220186194FCD3621607000C26B7E926551F8107F256647F4F3A2B43136B04459EF1928489C0B4BF12972990BF3F75CEE3082FB88AA3EAC16AE5904A79A9FA52315C77826A5309ED8B5BA1109AA96379FB9D4628317637D864E79243C2CB802FD964176CB47EF234F890560A3BCC0E940111174904602A0B4ECBFED94C475153235955D0AD147E7602739B661839A11A1A52257C6C003BB064AD2AF230BA606462B493A860C02AA62A5727E1263E54680C176151010419E437D4319C118D9A687676605D9437E950FCE770F5E9A52A0F46A8CA57441C2074FCCAE08E5638DBC30413B11FAC00EFB2A337311165393BAB1070AC4A140E2EB12D55978BD1114A7D19B03765AAD34724E8C603B635D5DD3C5F53B7CC83A8811354DFA609DBB0A8FB21553118C41A4437768687FBD8BC00B1983DF56213FA270506A15EBA99B87CB294BC817A23CC76165AC22E676642279E8751475C21B3AA42687174E433886689B171308141E8613E01560062410B8C154F11A5495274204EC75ED373E4E336D7E8BBCB24CCD9AB812CBDAB869F67B19941E10C9AB44A9A3055BA19FAA1812068958C37B48B796F1E869768211BCB9B31F6C49FB27B03AC9098618C9AFA5618F840EBCF75942316E687C2BEF3A163CE37E8016C1F645BB5BD2AA2D4137CF60476677CFA3685E68B188096B9CF3DBBE521C77CC47AA9FB007CF1C30B72876F52351E9A68E09F59A945887F4368EB46741D0C25F27FBBC45C36510496626D3013C128C6051B2D8336B30D77462623E4E59A01A27B1526C594A0894863610F757151C847410A5AF63E95D91B925CA1791EA788171A4940BE89E5F6A50D554ABB33282F057AA1630359B80AFC958B54C612902618197B6CDFA0C6720F36E070824AD372C499895985111C756739AA8ADD2C21940920E4D3379362A16BDB20E22A6BB26B079845BCDF32A20646B480D6C9ECB871CAF0A38F98662D3A9C89E8ACC78842F9C2C76AA79840E5491AF6428409271E6349CAB281692127B3985C547C009DA497D4F4424DD8109D52A476D440E457762C664683E8364C26C0EBBC827B7967207690C8AF5BA38F4215D71652146434A2B42CD61804D77BC61BAAD539124AB6B414341A8677A8DF0A9666E26BFB3300204194E24F350BEE636575C069272BB6FBB34A5433D6024BA6643B02625C41F055FC049BAE48A7D754681829A852C802F53D34E6BECA36852CF62C02D3D4A9D92A1856195A0C6F6727EC3291FC8CFEF7BA3838496FBF89815B32CB55C4DDF075322377AFFE4C1C6739130015D53E9272CE826C63252F032059286391164B950F921BFF53ECF5767F0B6A5A2C2724FD47F378261D5324380646237355276A0291A0A085389C210F5A5A9380322D2BD8C97ACA6DA7C326A8F765C054BE323395AB9383B7847C741E6EB1FA52C5E78D3856ADA3F19DB9C5AB914A71A88FC049445C3241050BB65FBAFA969C1B5E47C3E988D9CB022836780313A0BD728AB51627FB8D478E2C62163F996E14A0CD52859FE32B015129EC6581742A6C48B95953E70CCB73299CE847ACA77609789AB6496023491838CC9C0B321CFA8DC29655A86ADF8A149BC390959776534726134016C9B1B562C2EAFFCA6C9A53546FC7DA2C222E9545AE6C79167706073C0BF41CA0A8FF18C2ED1C4955A282A79C57E71097E67CB8A930ECEE0037E4BA749FBAC51B06890736CDD86184A08528C308ED659477BB721AF5CAD9D7477D9EA7FDBDC558CD455EF4B07AC746648A384794AA1BE7B22B9A507B1DB6A6DA96CC6146471F22F55D7C0FCC106BE7C5B30E634E381873188A46561981CB972B981C51CF3C49B2961B795AE260CAA1AE67D03717EC3A23819F5FE2CFFEA19119C220C5832EB7FAFBF2279D277A8A7D1030FD1F35806D1EB7C4EFEBDA7A51F21044515236AAEE733328776D292038C722EEAA1AF83D6078CA796D367EF6F824746E006FB70C714A96D19D4F1D2F5ED39DEFA727521", + "E931C94E02ED9F04CD60B13068C5A229CAAF01A0D929F62F21804D4297670D863A382EF306540F98C897015E2EF56632503FA3DF924FA333A4AC684466BE8E312EE22B41FA8058076EBD39C1D0C3A0CDFCB6A78BA2B49AF9242943D9D16332DA270017E6EFF53E039DEB7BE6C50FF8158F94FE08C12646D418BB456F53B8A2B80ED0444E9BACA0D88107A7E2D7F69B58E3793D08C0F2FA575136C79A4BD3FFBA2689F51CD1FE37D3F9331CE670A8B9B9F4F15D451CA0D2879B1169F178A7EB7CB488FA1D621BD57331BB72B34A885A818B99B60884A0D42E85D86D66486299B18F7AA4456AD70D2B5CDFD5B8606C845CBD3D9D0A928DB32826F46062132A335EB0195A4AA287594B584E98923E7F2898BF443323A429CA33DA777494885A848B549ECCC435E8B8D3940918A241FF97B03C14D855037E4555B98507050D1B1DFCE68B96FAAF562E3F3307AB3DCC1C822F16C4609BB45616D6F45F48BF54B31914A4EC827CFF8500AFE3294297AD85A8AEA3F3845A9A3D06CBC5FD2BA7D61689D2DBF85765F8A673D3244C27CF148CFD66BF360981E35B9EA1CD022CDA262F4EA81E090A1CA1A3C9A5333EDEA755755752564560F578EE2BC99C227E621C53489C26F3E109AA18FC3BC01FC14BF473F3B9A9368069CE272B2A786C6FB6BA5120E89B3C5A403B9489DD065AFDDD81CEFD11B8BC5C4AFF5330CE8BEF0F5DD17748FA240CA3D83D17EB96EE6CEB39AFCC87BB83FD0DA8E2C8E003952AF86552CC3345D49BBBB363729B8EEA09FECDF7F3BFB1FE4E03EA9A71B45100286E76E33494C0B1C6E2151B6C571C239EF36757D4D46FDAF694260DCE0C040DBE230C6F9BF195D2CD2D7B460EC036FA10153A154D578BA1D8B74A52E642D730218A551835D76103410C433C919732171EA4C4DB1FA9CD05216266A5F14888C8540016AF50D9ED4F7BD4B1214C774CFA9D032A5FC0A89073E3259A05290C7885C2C4FD07DE218AFB7BCE656E54EAC77F34C23E9024F05AE641BA5F72F342DB172998871F94CAE6206EF179AF6D728A442E0F91873079AD49A6F1E348226263E039F448F54DA473", + "D471AB1DE1996DB78AD89F021821A9A2005CE55B6FD74D867123AD814FCA5AB9" + ); + yield return new + ( + MLKemAlgorithm.MLKem512, + "8D0698292038F9E5857CAA46755BCBAC626E068B493AF1BADCA93D697CB7FAD685D9293244B26818E3B156C9A796DB53E06B736CBAB1DC0B4869668F078107DA976730D5ACC1742B47CBC3F942693D443F30CA1F51E472D98A33C1B9A1E37894C98845A6B369C71611D69173BE935170239594A30F8A7C241BE28DDC1129ADCC72EFD26B3699A2A46829D4A20643C0AA00E9286CB8B2B8370268FCC30C4B1E81363FC968203301B8AE52957D169E16C197A8267D06897B928A2F7915572CDB4650069204C093F18C8061E1B79858349D831F9C8C53A93891999A739790777683908D2634C3DC53C3A03349C274C16A1BC03B0658A6A230105F63236BC4AA147DCAA566294E137480BD516019BB52B2514A62C894BC081EC1793C708B4F76F692FC93816565A09CD2662B6344C472C5FE141A417381E4969528469E2EB873E8871A5774A583246253F62874197E03A81BA8E1550E6AA75E70AFC3978E401B6DE52CCF898804EC102EB037C98ECB20C9AB9218783413025030165E13A44CCEB71BC2322E55F17309E555BF96BEFCE7AFDBD25BFBE149CF7B1464BAAF78222171153DCD3A3774BA059B9BA586536F5EC63635F17CC3C48DD07975E063BEEF96C165B82831384FD8440695286CFAD51E3AD2891CBBC96DE5B563B20D72D85F921647E5BC912F4B0BB75C0C790694745AAC2B9C3B2C5409F9D505B44952AEB6506CCB1CC2D506F0BBC3BB442DD85758AF658DF10C6907650315484C27798D7EC7AE577037B30A48DE13B377035EEBB27A0FEC6CEE366605B40604B420CE92705B9B83E1F93D5AAB9C2FD668E3839DF11A31B101BE639CC0F5D05878E32F351680EBA50F021717EDC5835FC7C20A72435BD91BFDB0C4B68731C6566E8F1C7F1FF10DECC14EA857B008D5C37178826C280FAC788D3DC54B0115BF0D9018890B2378628CA158BA91657A576688AED610CCACCF96E6B5884328C091569B12785C4C054CF83C42E06D40B6BB763B449C00C3A7D9581FA3667F22BFC1A750B907C87BB14C3723C9A880743ED5A181B16D8435B4A4C98537E20086D89D28AB3327627AD75291B87561B97631DEE6FCA7F77A1792E99587DA9456B5B98A53F73B4A4DBA89A68C", + "10575428C648AD91083CB07F76AC26A36540CAD99D2E9C5624E8337A359F8B5748C10C7D035085B0F429A123649BDA87AB285FA96237FCF449CA78361862B10BE3C0377957150A12D32B1D0B8959C45734F91C4BE9A0ACA88B1CA4D0C7BDA00DA618475F6C34D668498DB75DE569303259BF20411BFD566E2DCBCFEC4B055172147AE747881B7076136178831A06A9A2256886C35AC35B5C3F2C2C38CB4117D4A1187803ACB412003BE96052EB1174965A172890D6B034A0EC94D06A368F819284A547391149C34469B61BC8D0F29A62F0847686C15BD9327C1A67ACF0C5E9141CE34A768213002705CCCCB971EAAB55332A42EE472E0D6263178C69067A0AC52021DC4C798FE8A1ED893F34A2B48B405540C086204A8B869B141C186D8B3946070AA5CEA055F8F420705B64FDC13EA580CA57A7ADC23659B7EC1D44AABEF7A9144F93A1E4411A47922CEA0BAEF1151C8369C3857C17420769ECCA02E6B162D7865B7DE37EADD75DDFF75BC2125988D83F3CE80A1331878B277712234BCEE101F723422C7227B536BF352131F0A11DC56304EC65928AC436343B7826268221F4A49AA52389674D8B780E7EA72F69B5443E622B0FB9106532CA87B9A16C7387DA2BB41A643A9287162A90803A10BCAF68309C2B3F0EC8770CC09A2020C8A2DBBCAB1A192A734961F5BCC22B7CF6CB314C6B9FFD5332D4C5028B11632FC66A2F56421D7C8A07656F5888701C9CB6E4FA29EA692B0A8C97B34797CA83B09797A356A28EF9E3A471D82517FC56A306AE8CB396E8CC293BC849A443A4273C02F964C62EACBCEE86CF988A9E75164154A4611773885814107F37C5BCAA6FBE3A4C2FA1723B670E5838289326B182365BD0CACE1C60BDC1C35BF5F3CE653A5EAEC6052A1C14868191F4B30605605BAB8B06C876741AA74F4CA8CEDF719F8817A7E4C536F2260CADF0683A92B136E03B90B51218A826B44584513B131B7133A5479EF808AE2A186224B085AB1197883166F61AA270762238EA76E3C29E8FB35F0D023CF01421699B5DB739227C12A1C462ABC9B0BE92E45AADEA1456B386B1203D2B94718D0698292038F9E5857CAA46755BCBAC626E068B493AF1BADCA93D697CB7FAD685D9293244B26818E3B156C9A796DB53E06B736CBAB1DC0B4869668F078107DA976730D5ACC1742B47CBC3F942693D443F30CA1F51E472D98A33C1B9A1E37894C98845A6B369C71611D69173BE935170239594A30F8A7C241BE28DDC1129ADCC72EFD26B3699A2A46829D4A20643C0AA00E9286CB8B2B8370268FCC30C4B1E81363FC968203301B8AE52957D169E16C197A8267D06897B928A2F7915572CDB4650069204C093F18C8061E1B79858349D831F9C8C53A93891999A739790777683908D2634C3DC53C3A03349C274C16A1BC03B0658A6A230105F63236BC4AA147DCAA566294E137480BD516019BB52B2514A62C894BC081EC1793C708B4F76F692FC93816565A09CD2662B6344C472C5FE141A417381E4969528469E2EB873E8871A5774A583246253F62874197E03A81BA8E1550E6AA75E70AFC3978E401B6DE52CCF898804EC102EB037C98ECB20C9AB9218783413025030165E13A44CCEB71BC2322E55F17309E555BF96BEFCE7AFDBD25BFBE149CF7B1464BAAF78222171153DCD3A3774BA059B9BA586536F5EC63635F17CC3C48DD07975E063BEEF96C165B82831384FD8440695286CFAD51E3AD2891CBBC96DE5B563B20D72D85F921647E5BC912F4B0BB75C0C790694745AAC2B9C3B2C5409F9D505B44952AEB6506CCB1CC2D506F0BBC3BB442DD85758AF658DF10C6907650315484C27798D7EC7AE577037B30A48DE13B377035EEBB27A0FEC6CEE366605B40604B420CE92705B9B83E1F93D5AAB9C2FD668E3839DF11A31B101BE639CC0F5D05878E32F351680EBA50F021717EDC5835FC7C20A72435BD91BFDB0C4B68731C6566E8F1C7F1FF10DECC14EA857B008D5C37178826C280FAC788D3DC54B0115BF0D9018890B2378628CA158BA91657A576688AED610CCACCF96E6B5884328C091569B12785C4C054CF83C42E06D40B6BB763B449C00C3A7D9581FA3667F22BFC1A750B907C87BB14C3723C9A880743ED5A181B16D8435B4A4C98537E20086D89D28AB3327627AD75291B87561B97631DEE6FCA7F77A1792E99587DA9456B5B98A53F73B4A4DBA89A68C79BBB888549D8E7F789D27A3513B899264806953E9650240F1E5740BBF9B6598839C74574CBD32E7837877F7020480A15F6E6AF143F3C078AAA0DC6D72BFBDA2", + "3AE5A2271AC46827EB9B46E6A6AC7AD0D338B2306CD812CB80ECEA078687858E575BD61D4B08BCE51D473D11AAC2C047A346225F842775611A4446CC43E924ECF9A6409B6A589134B5B4C46F8478F0994E90BCABFB361935B4A944CB1D5D3AB38001242EDEF3C0BC192496C2FA6EF67DB276D36512A867FC9E6BDA9191388F3798A4D1D7A4A236F1F026DA54D0BBC0691DD867F424770A1A050C26D8CF80C8AF88780262F73BBAD0727F6705048A32D02CB536137796A6664F03ECB0FDD76403A8AA6C7B39C62A1DA2981A6AB36C987ED2BBF6088C868F15B55955329B17FCFD4EC19B69A7734610EABBEB02491E786EC1AEB85F743593E0880FB0B997F1A81E484802C39D4293FAC089886EC4DA1020AFE810CCA5056CED3AFC8AFF69E1B8DBE05B3A2D105CC55ADB632242541AD4241104B1D789DD6496FE7D22D2173E409A18BEE297F30B9EBB76275FCC07988D464A6B3912AF1136BCF32EEB1DD35EC7CF179D55A0EF4C4C2BA9740BE3A24F33EE1D1B2B7881A71FB9DBE7F89CF6944519B14C6EBD4288CCE624C59474E861249802337B1C992318DDF75ABC03E492D5BA80F3A6AE2D693EA379DF7773B5272E3BB432E0AD4B56191C8ECFAC229E133FEF9B082B3323392BAB98B7CD3BDFD03684F8B4BFD339792313DE77B2A7AFA3BE806B9EC962B825FF6D6CC8E052A33720C9EF3AE81E8207433A3B6E39E90A5B7FDDF6FD4540760FD6DBE7BDA313F3B46B5B4587F57DAAF6C8990C4253182A3DA94AD6CD3414858AC95A87D5C2ACDD0B6C3D48A2C78C4E9A897E33393A257F428B1826B49F9DA7382664447C7026BF5A009C495EE3FBEAA175DBAD78FF7061F7D1D3061E205F2295AD8837648E804271BE3BA05865B767B7032FDA57B1E77097EC877ADA26F09CCC22AE7A2A510B44B24D2A5C5F34AE3EE6DEE769469378952FF5269FB8EED7740D473D8DABA32AF26DA0ED40AD839C3D02A477B1E2F090ECD06BA910066EA8BBB2F32C0A077ACA9E1866C175F74428EAF9C5D0B4E8A949E7C5B8B68CCA427F879EDD2B7E32F598885ED74CB2BF43853F9118DEBBF13CF6D171BD8F", + "5990E7D7C98BA9433133EF4131E1803F83A071D27B5E3B28FC6C21CB6005A407" + ); + yield return new + ( + MLKemAlgorithm.MLKem512, + "1C83C3DF2509E3C67E58E236D479779EC928C1700F6D4162AC8051BCBBA7AB47B70016A091C1B2A73BAFF47119F2B793B8A66CF4877D972110B7FA3C1860417B34322C449052613CC8005C852B111DB94B06739F2AC286731A3FC96A258727172DE84A5E046C0C5780E3016DCC25910960BFCD0BC86BF50103D5178FA60E6C8B9CF0847257461167265D90C541551B6E672B224BD6711AA31315104E194678FD6B2A8D32311004001149CF4CA3C8154C4976178DCEE33375A09D7B3C447FF4A6BD4CA8CBE957CEA938D2CBA7A24093205475205C4000E439F6E7A40E4898A33CBE30CA3B7286AC49C9142230016B8A7C8F4A402F43AE0B3ABDD977077481510349C09176978C92546A866D0585C2AC12927A0A6D79B1A39644AEDDF6C5AF1013A7B661E875CEA3FC95BE5A172A881D0B63BFB018387108646E7207DEA9B839CB0DB26B48F4E918D55ACDF2338C58A7ABF0D2561F299283BB7D2D8670D094009CC427EB0329D5144B3F0B683166CBF9763F4E58584B6627D4175162484586201E75E0CCAB112F6339AD01B247E4A96C7C769EC5F9B107D9CFF352C3F3EC61E95690999C0498FB16B7C539E9372E9DE99D50756389D63B6691C123947F6B0661E4403C0ADC6364B1516668C175BA9FD8EB462D3532091179FD67853BF7C2DFD5A898648ACEF8AD42B145E67701F2820565AC4D4DD9AF2D395469192B884212F00BC30391BD711C0141814CA95C53B6455C848CBDE2185592B9C84CBA5F43D39F6B6B77F39B599ED9568ECA342D71047C4B55E244B863B2725E8865850B9DC33A4DDBE3AA05D597BCF52901FC54A82635397C992C615F73227A12A6595D5C28B5B6A685CBC335602FFD2184A75243FA639C488BC14BD73CD1D6373E7BAF72453F1EC073F5A6A26D990F48570FD769838361B48313464906B8DEA60FEEB1A139486DB1D7C2F63A6C48D54E5BE76E835026D383AD38952E5511BF02F857699CC16376A425999DEB06895E1812C901CED44835D35BA7864A5CD2D4B21F0B9E6DFBA7D870B07AB401BF23A3B02C11CF00CF7BB99BA500520D846B41B81BBA5650A6F118AF8A67688F81B0D2500048E5A0B5B6037F7A0C2EAFF45D0123620B115E4B92A4", + "9AE711EC12485D079B373C1629772BA9BC0A6B81232F1A5EEC91330FB2BE42F32B5687614C5C6C2D1A42E292A0BA30CC6A51A258D07BC05118FE29BD53F48988A2BF0F2920008A3EBCF28872BBC5DFD8931E987EEA2040EEDC97D6498235E4767C976A7CD1B850F649D8C680CDCAC6D2512CB1634A34809C65940A0B04562AC5655947A123B6B48CF72248C6C47E600B5AB410CF0193E7F4AF5EE17C2FE88EC145971164B5CE6511360311271090514451580BA2E3AC8AD50618FFD508CF250A056650BCBC0B36000FF82664CD633F04E6B85AE02AE6424370F4443D3564F13120B617202633228FBB9C6928741A3715ED5412A57340DB9BA67B0941CA9908340A3048335083BB2A3BA3AA0B50C05D668DFD64A7391025427B48DDB1C4EAA047CD4970A397B1DBD4975A59375642A8558A043FC1AAAB384143BB936261B87310A1F4382C6D465A1C4A46B885CA67EBBF863A134D7B1387D7347A29783C15AC16F3C628A52B5706A123DB49E050374123718DD724008CC24752BC88E5A0EED6B38702B985864A2EA099109B51DF1975F695BA4B7A68B14088DA656B77D68FD848042B262998D4A1F376CF77478B9943A40A031744780B3B346BC1DC9AC5D57367AC98D8DA8A5B5A4C07D9BCB9D7BF30524DC43B0F47439D4D115ED981235DEB3FAC400F1433447EDCB685E69AD3F749D4A54F34E88BB0102C3EE4C6BE8135B993459AEA43C3B941CB4C2A460C3C6EC40A5F2553B3F76D8DD2AE13A46E367A0F5E8B1C31042E5AC45D0DD26FC1257CE3BA7A63B441657CB1762AACEF154D41BC93B3B17997855C78F2B37AE55297D8C4836338B2F9B76D6A84A0F2908334801E6BB9EE2506250063F108AB9B48538D7256EA5797DFB90BDB943109D2C6C8C83751736C6CD1768E24AB724AC709B1CF97A4754A152B187C334CC79FF4A2A721686B483B3085DCAABC5BB451A916CCF48BAD23233FD6729BB2C8E58257FCBA5BABDA6BAA49B23304454F79AA47215B3F51CA9EC429A49C8AAFB55AAA854CD0507B0E6902BA119355F43ADEB583185C0D7FE1925A468B7C583D03DCCC2F7471D985351C83C3DF2509E3C67E58E236D479779EC928C1700F6D4162AC8051BCBBA7AB47B70016A091C1B2A73BAFF47119F2B793B8A66CF4877D972110B7FA3C1860417B34322C449052613CC8005C852B111DB94B06739F2AC286731A3FC96A258727172DE84A5E046C0C5780E3016DCC25910960BFCD0BC86BF50103D5178FA60E6C8B9CF0847257461167265D90C541551B6E672B224BD6711AA31315104E194678FD6B2A8D32311004001149CF4CA3C8154C4976178DCEE33375A09D7B3C447FF4A6BD4CA8CBE957CEA938D2CBA7A24093205475205C4000E439F6E7A40E4898A33CBE30CA3B7286AC49C9142230016B8A7C8F4A402F43AE0B3ABDD977077481510349C09176978C92546A866D0585C2AC12927A0A6D79B1A39644AEDDF6C5AF1013A7B661E875CEA3FC95BE5A172A881D0B63BFB018387108646E7207DEA9B839CB0DB26B48F4E918D55ACDF2338C58A7ABF0D2561F299283BB7D2D8670D094009CC427EB0329D5144B3F0B683166CBF9763F4E58584B6627D4175162484586201E75E0CCAB112F6339AD01B247E4A96C7C769EC5F9B107D9CFF352C3F3EC61E95690999C0498FB16B7C539E9372E9DE99D50756389D63B6691C123947F6B0661E4403C0ADC6364B1516668C175BA9FD8EB462D3532091179FD67853BF7C2DFD5A898648ACEF8AD42B145E67701F2820565AC4D4DD9AF2D395469192B884212F00BC30391BD711C0141814CA95C53B6455C848CBDE2185592B9C84CBA5F43D39F6B6B77F39B599ED9568ECA342D71047C4B55E244B863B2725E8865850B9DC33A4DDBE3AA05D597BCF52901FC54A82635397C992C615F73227A12A6595D5C28B5B6A685CBC335602FFD2184A75243FA639C488BC14BD73CD1D6373E7BAF72453F1EC073F5A6A26D990F48570FD769838361B48313464906B8DEA60FEEB1A139486DB1D7C2F63A6C48D54E5BE76E835026D383AD38952E5511BF02F857699CC16376A425999DEB06895E1812C901CED44835D35BA7864A5CD2D4B21F0B9E6DFBA7D870B07AB401BF23A3B02C11CF00CF7BB99BA500520D846B41B81BBA5650A6F118AF8A67688F81B0D2500048E5A0B5B6037F7A0C2EAFF45D0123620B115E4B92A400F11997BE7A68FE85D93A281B31BB1B612287B9E94659A2480C2278C53FCF213F532ABD59FB62728FEF47CA84C2E93674EB6A518FFDF590EB66615EA7174013", + "111C9A3008F48AD675BF25B97F3B3F7F12793521425025C47645413AED3A2E8A29B7EB5DD46F4B4C8DA0FAA8140B83CAE325066EA3641A6001E475B685B4B348FBD7AFC0B07ABB26E7163E32F3D4B1FA7E7E15AFE168B31F7476697161B6E44374E13723EAC77C3055282D60195AF71E4799576FFC7C59D85684846F05BEB47465E977DD7E45120D0D3F7DA6AE7F43E3C9F958DC26FBC0D4E5C0FC6EEEFD392401162CA36872FE996B213B25814D951AF84B3E19BF14A83E35CD91B4434C5C9F47FFD08905D9C71B86E82E433B6391573982DB3D7BFE8E1E656C60809E1F91A7846732189AF4616D5B4605E224CDAAB8D3E7F0A80792F352591AB59C9B5494842057970E9223B793C91FFFB44A87F999BE7B964B4A0FAA1F3DE424320EBFAEE29EC27DA4FD8E01A85D0839DCF4FFD2494C932F5CFCD3C4C608266A43312E4E8BFE0CABED2FE7608E387F04FAB278A8F84023571F8E3069E3664FBF25ECF33CB14F5945D924609BB7F956FE82FBB3C122FE163CEAA2661D84EDD5DDE9D254C2C8C1F25BC6691E589BB83B657BD88619A88A0A28A42DD4DE04DD762F83FDA21559CFECA8143DEAFD40644B5F789784E5A4E6E8BC592DF66D2F875E531654C3A55D7B2A06F4E3050A83E9B1AAD62D185F3BD400E5964723E793682010161D8B5CA310F87245C678C8C739D2E5B473B409C4418BB21581BA67EFA8069E4D10BA6D0FE8F8E6E30FA322B2E790238F1A51998A66969A50785FCD4215F44FA67EFE179FD212E91BD3BD8528FBBEC7FF132FCD228A105CB8FCB4C08AD3828E0FCE07779995DC8ADBA45F91BD3A9B8D46BF8E837368A218C5104BBB9ADEA8334C758C1BDB17300AB06B1B5442530ADA971C7E55FF053EC7AE0A4F0410324D640E287865E39E511CC957E4C949B21C0CA8B98901AD6636B54D6DC12C86FE740D4AB07198E8C17C7DD28EBB94AAF1AE60AA724BE97401E056818F563FAD982E692F3696ACD79BE0D418289DAB86F4BE9008D1940FD51657045A10BC2B1A6C55CFBC680765874E654FDB543E4D78D86626A407657D2EAC0C1B18B1E9AC1353ECE898F1735EE3", + "6E07D03EC7EFD80F60B384F8A1AC9B19D839802A727ACFC365549A26AE29DB63" + ); + yield return new + ( + MLKemAlgorithm.MLKem512, + "FFBC558CE050BE2C7B4616CF37604F4D736991179394CC379A87BE8A1952CFA51D35999124A44A2B96BCDA9519E9FB1F40A13F035A926A177EBB37141A3081BAA0A6CB120A35909FBBF5A245C1BB9343C2071A7750689847A246D2306137C590CDCAB6E2A355E00CB6A399968F3B11A5897658B72A3A466E71C339845CC0C9D8C985D63B31703993F24293F70D5DB6A886DB658FD43C7B2681784062739451453256C0350EC31C4E1CD4B06B3BB2EEB19F5BE27DA3E564F92486685660004A3C972B4BF872859EF781DD90079DC343C8B1AD8A4020D90C00FDF0493DA7CFA0B25335482A010A690C648227A3671313162D5259CD0162CDA68F1CB291F844B845D9A5376BBF8DF67B374B4DA47B6CB7AB0C81461CA3FB591FB27A9ED0791988B8352055AD469BA0B66AB7D4A71497128309C45495A27E73B86A32C05A257FFE04453337C66C5B55D27BA88AAA36BD371F17DC589F01C883587C409B695BB6455CAC976A7A48B5136DCE1CBDB8F7CDA119B3AC5B19E622086BA77689D9B351CB1BA144954F51C2CA5B1D475A0582C0B13006AFE2683CFBE59D4DF5CD6A7A7541428DB6F85C7F9C831C412A17393A76B9BE7CDBBDADC38510962078170A68D60719223D8075854BB929EF4671D1970B1629397287372F328370DA198A17CB4D19A55F25CD37C866420587CC2C1AE578C2768047033546563567CDBC1FA8173D53B1CBBBB8CC93908C97F4620BFCB87FE99051E47C08884699F72ED4782900C89814001F7475673DAABDB4359CAA58044AC22089D73915416F81E59DB06808EFE31ABA4017ECF25FBDA730074C75867B6C8A7C37A79670E9B8CE8D3B7FE4879E24296705B424A764BB9A320F7D695A6C43273F7706F8254DAF845BB9A6459D643A94A97453468ED9547C6FB0C6EEF280F6833F85FA63F8EA12F65153B07395C609B37FBA2FAC39416C23C3EBC3A45DC892A68C210B49614FC966A25409A1066A83D7C301B4BE1948BC24565B3810C852489DAA42A8CDE93489A04E2E622AB2003410753D770636F9B06527DA6274C10BF90C7B1B8179F817CF5A4095D627B1F1B433B17079818EA6E206716FB0745D3438F995ACB85239BB378CB0A900A2D2C6C81E", + "D276B7EB86B21B95477AD26C470A942696AB91C570ED5CC531D6704B752657AB7416E5284200BF13E73308F86E225CA057B03D785908B880939D439419972E95155CE8A841B552428DC00FE5AB47A35979F68165960C77A039BB5CBC3F80CC4526D402E53C6F9759B7C7743FA150CE581925295192A912191A3A0EBD215D3188670FF21D845080DCD1B73DA65887D324E6B20E67A1721E078B26CA1BE91A5FADB6BF40C8329C917576CC7C0B20BA187A5075D245464BB3B874A81286359EA66913146273B28866548D13C0A0CB91337685382556C88DEA378AC37104A0279FB647B459C0132A2152F132D1E71BA721CD7857C46F217EF4AA1E4BB484D3D21C2495975E2BA7A0C03B617B318B8773728A3C54575832860CB0968E5E8265714AB6F8659D881183956AC1368627387130A479862492805C7C67E558775B566D1D0521A82C14DD0087473303F8CC93EFD45D14653982C871F807B8BB5362C5079AE5D51FEC1907797C07E48B46A0C73D9087AD8B63972D0166DE89887974B0FF989D7D5794863C710529462B48BFA85605C4F1425C6920AFF484DBE116EBEC06AFD4C406599EFBB8929468C0FEC5B0D95344FA3AB9CB2765D550661AB1077E494B8A88387BDB016C0163414275337896EA797C59467F13E035ECC61DDCF0A7BFA146BB36C7D8720ACA12A22F4070A7004D1877769C3A2162DA0F23F88BBD405267E642B2DBAAFC99A9E9F91BC1C09302E15F165B08836CCE76DA7F317AB6C14C1CA593CE27A7048E70291D4B8EE6C80EE7039F9964608F08940D8651D0FC764C02640B019D8C828B424840FFA00D1686246A93010F4B97A2E37431010A007AB552F8575AFCC64EEA0C01EA791F4066214637AD706864B353F54B30884B2E11A1AE4BEC0E1CDC8939057261A30506975A64858079E431D6437E45D30F899B9DC4C7734BD613A546213D24B625A0B4D289484973C8E0A3C57797514FDC032C0AA9CDDC3FD6F7394112A83D26692499C046D5732ABCC8437481A4D82E599813361772BD519884693C3DC8CEABBC1747F4ABC061725F2714B7618BD04563A15BB140E00AFFBC558CE050BE2C7B4616CF37604F4D736991179394CC379A87BE8A1952CFA51D35999124A44A2B96BCDA9519E9FB1F40A13F035A926A177EBB37141A3081BAA0A6CB120A35909FBBF5A245C1BB9343C2071A7750689847A246D2306137C590CDCAB6E2A355E00CB6A399968F3B11A5897658B72A3A466E71C339845CC0C9D8C985D63B31703993F24293F70D5DB6A886DB658FD43C7B2681784062739451453256C0350EC31C4E1CD4B06B3BB2EEB19F5BE27DA3E564F92486685660004A3C972B4BF872859EF781DD90079DC343C8B1AD8A4020D90C00FDF0493DA7CFA0B25335482A010A690C648227A3671313162D5259CD0162CDA68F1CB291F844B845D9A5376BBF8DF67B374B4DA47B6CB7AB0C81461CA3FB591FB27A9ED0791988B8352055AD469BA0B66AB7D4A71497128309C45495A27E73B86A32C05A257FFE04453337C66C5B55D27BA88AAA36BD371F17DC589F01C883587C409B695BB6455CAC976A7A48B5136DCE1CBDB8F7CDA119B3AC5B19E622086BA77689D9B351CB1BA144954F51C2CA5B1D475A0582C0B13006AFE2683CFBE59D4DF5CD6A7A7541428DB6F85C7F9C831C412A17393A76B9BE7CDBBDADC38510962078170A68D60719223D8075854BB929EF4671D1970B1629397287372F328370DA198A17CB4D19A55F25CD37C866420587CC2C1AE578C2768047033546563567CDBC1FA8173D53B1CBBBB8CC93908C97F4620BFCB87FE99051E47C08884699F72ED4782900C89814001F7475673DAABDB4359CAA58044AC22089D73915416F81E59DB06808EFE31ABA4017ECF25FBDA730074C75867B6C8A7C37A79670E9B8CE8D3B7FE4879E24296705B424A764BB9A320F7D695A6C43273F7706F8254DAF845BB9A6459D643A94A97453468ED9547C6FB0C6EEF280F6833F85FA63F8EA12F65153B07395C609B37FBA2FAC39416C23C3EBC3A45DC892A68C210B49614FC966A25409A1066A83D7C301B4BE1948BC24565B3810C852489DAA42A8CDE93489A04E2E622AB2003410753D770636F9B06527DA6274C10BF90C7B1B8179F817CF5A4095D627B1F1B433B17079818EA6E206716FB0745D3438F995ACB85239BB378CB0A900A2D2C6C81E65325EF7D8E1E3467815EA3582ED63D90E99CD0EF85185D3A2CEE9904F78D67A606479059C3920A06895F8EC369A9B9173059CCD77667520A7D276162AFBD25D", + "A6A2CA5C790E38F2CA43AB92A12A914B2F85284CF46F42BFBC4DD40AE65B1BE7D821F91EBCCC986F3A1669F83E7D6F135A3BE09D0D7FCFF7F883DE86CA2938BDD3780543EE67740E0C8BFD6FB6D60C7E971161474A4D969A5C8A535AFE14DB3C890B511DA945C53F925AFF4F9329C097DD6E3EEA93B12D8DD5A05D89510C0019266137DD24077708E2F2C63FA7CEBD3B736DCF3107F1FD1BD90939788BEADE520E23643F109203523E8237D5AD1D96832188206A50023129DB1400B00CB3418C1D8FF15CB23AD339D669594A3794DC189DE19871667D7501FCBBB880C4CA9C87BBC1A5482B218450F2A830BD0CB084E70B0D123D7CBDA0F7700FC4D2AC4B22DB12DDC590807793A2475AB66E0B8B6A3FA2A80211E1A752539D65223431604E6E583D3AF71BC5CE4FB85A7FB643F5E343418B7E4B92534D78E37528642F7ADC915114CEBFB2A5CC984DAA7B98519523A4334C1289EE33A2E9EA80D3E3F92EC7D4A6D4F4E7D659D1B7DFC00612D74ECF4DE5402962C0F03117E48D0C739314E4C4E233AE779420251EC3FDD6E364F4CDFA3747C543CA9B57711143FE7E16E4CEFAE7C3FF9F53398FE501104B886EE7505D8EDD3B258A56E629DE61CC656B721A7B4A2C2A03CE5A222AB7FC6A2FD1992D88CE5B98B314617BB3B1419E4DEADFFCD7F2197DB0B150EA87BC2EDFA11DC986720C295D3FE4F78F40C00EF835938B0882D4453E71EE63BBB521A79CE857BFAF732D996973B68F587984045418FF929DDE6B6E82F82C910222828AD5F1D31093B9081D592738E16018DC9082BFB233EEF847120D6A846E5A33F772C989D37CB274F20BA7829D0F7797C02EFC7C2260040497F5BE3811068473CC5A5B84C2AA29749F501D03E4ED64E77EE9A2AF125AC8A7C313C892BB3A44646491E2F10D805436C0A02C164C38DA178036FAAE6DDD64585289BAA942CD30116ABC59A9B455D349D09A9AD7A3F59BEF76B26C026361F0731D4B8BF70D265E38818DF36FA623C56254D826FF2AF9C28D519843B3534741C0B6A78CF094A6BE8434FAD989BB33ECD88C98F02E3BF37628D48D1736AE2465A7", + "405E1E3E8A545D56132D85DC38D67A0CF7ABD99D61E7C8A55D2E7260F3D96C5E" + ); + yield return new + ( + MLKemAlgorithm.MLKem768, + "1F2962ECA97FE4A63D64804B5B259F2025197F0B0EA9996326D24736553ABF113594E122AAC2C62936C1BD75689E240CED9BCE098212067776023A4954376EAA342687195E548160835224283A4606207C6C939376030C91BC3FCD6466810C5FA361488824B35C693DD8FB56DE2412B86A9ADB28384F908B23ABBD28307CCF834D3CB29F3E1AAC65806F4084974CD7037E2B84F645733FD660D3C246076706856B2415B0A234A29A76532DD6D6320BD06AA459768FB067C7B28B8C89258C2354EC5926D23BA388C14E39A63F61D23D705B1B850C58804856934892DAA452007B2ED01C6196995C55C647F3F58BE2D27AF8845C2334AD27687A25E50BB6BC90058B181D7197C5331088B7AC1D18038AA9920145887247C805102B95F57235783A4847130E47566A60469575651F0137608395D010567B7866C8505E6DBB6F6728959C128C382414FA53C461850E7783CCA1B4265008642581A06BB0C410D2A791D0977669188C6231A4A3390DAC1B15243E41D57843C53E309A3DEE5BB0991A85109A716800866259054FE1CC59FB6A96A75C8503517EFB5517E8170376512A53C861FA35AC8C4B5E63756247042690BD67BB8E0C7C9E8F05C5CE48CAB0F1425E329072F87401634211241738C2CE97208C6A6AB609F03EF13387AC6C08A3FA61E53632677507711A25C1FA3454D86D7BFC75E668100D6A6A03086142275383E291097104356A0848724BD95C3CD89CCECE97421BDC67B0FC8AA0E0C2460B4AADD9033CFC60EF04AA6F39566E89793DDC0481109E532566D90525EDE57E8B756FDA7190BB89937DABBE2AF4239961CFDAD37F1E4B5BED5A4CB5637163840716A1CE2F2036975A640B6A7EF308690D66750CA05B9058772828BC458AA9CE47116EF459B01C292010B7449207EDE7AA38AB20F10280E316298E9C86B3B4B94E718B85798D5567C96531A6CF84BC806AB85E156A34447B15FA9FA5BBA5F1087189BB9D4561885B2547DBC5BC081C1A268A9EBEE5CB1D4147545044D11933F43871ADA5495C894793645B0BC472407BCDC5ECCE19F219C98532882381739B94E2366BAE2C543E68116BC30974149E59318DF3336204C22063E4481E688FE2634D790773E243A325AACA07AC65EED5BBB092B6371B519BC01067849E6BA3C5D9B4AF5D073BC84BB472C123F2C72C4B191C85405D63C148B368399ECCC42F208F62E75E14408BEB14101EE4249D2418C359AB05E5A3B60A5465637EC6A31419EAAB9458A285F684404C4A94425FF6806150C7111AD2A77C0616D45CAE9024BE5DE259FFD6C3C0E509DF484F2D219D5F3CB596BB763D4BA6C3521789FC840142A42D510F14EA44B3E9B573A49F9B0879CA5A5E0606639A7C67A7674124E2423339126FB019E00BBB5031A1AB9B3A71190459A16EBB0A196DD9CD5A152179082AFA9436B647A68111439DC325EA777BCA84ADDBD62FDFB61009A54FEB495A166BB35C9C426A678E6E2958BF52138F68711D623B41C7B4A97A241B17B3C37720FBF04BA3C175C96A4CED4C3FD0E4CFBB345A0CF48A7C0870E4353CA02B92A204A9C03A6287BA8E1CFA50B91C2E2674CF93382A72E8B9E0214504B97C18D60351F689392A8E44AA2C57DAAABE4CE52E3CDC2BB436DCBDECEBAE89BD2E392F0370092A66B4F0", + "BDB614FFC9BA80A3BBC1899EC855448E2734BBA74116181D1503CFF0B497C832B75998A5CBA94C76C2CCA25904F574080DFCB7B4E64D5D7547B2C2C5E4CAAE550098BA50BD6DA47EFD10A67C2502A8C7B42F4B2696846FD849706C014A6CD8B828012B4BF41BCE0041E27A4245231B954B958B1400A7721FDDE369C488BE6AF043A8C0A9CD0CBBE132A2F303BB57A4ADFA02CB12717B2EEA905381B110E61A6B506B45392F45313C51756D80B27B9398C1F3F1A74655AC08AB6801F651A1A378DE128F63D4BACE138330025FA3882BAA630C98A070395697D4756D7F0521EDFA065D36A7491B53A371080F97CA1FA0B93E544DBEE4815B92AC2EFB9005113D583A731E17B713A68373D5AF07E32520B1958FD9643B4CA70E601472002141A12424726114AC1FA65801C8659846E8A1D42C53BB0A3BECACB43161C7DB707351485258C4C373754E9774AC09482CE92A24EBE959973A5E12606440777B22471C3EC015F2673EA3B4AB844778EAEA88302446EE790C2E954B29738A90287EFDA113125170488964EA551451955656A788BFE4C58A7AC4A9F2BFA2DB2C91C69DBB332FC4B231DBF1B4AA914BC63C1C37380C2395874EC1C517F0C79DD0B85054668D93CB2922917F9593D49292353C8A0208A26C37738EF146E92A2E10C49904F324AFE1820EFA0AC5E5A4AB3585A097B6D35C88DD57B5AC0241C21A5DE1A581D5416C11CB1AF1B79374C746FFFA4DF658CC6881BCD5C875E925223AE8A56924422EE9091B21BEBE841C37B8506B097E3F3BC20342AE00307745AACED7090547C1882D32C60BDA724CD156ABF8A11DA1BB054A8BAB5C44B474084FA13FE2949310EB64239338BEB36BD86ACC923C4320510220545D8EEC2F77EA364870B58404126B501CAB238BACA52040DA2037D541D574A6E7C30B9877AD540512BE2B41AAF888295B1A38C0CCE4F023BFEA82EC0217BE5A7D6A6515C399ADE1AA911336718524AD916A186FB488DA793D214486F0E231AAB6075C0A04D6406286684D65484B8520438F021FB4C55AFC5A4C35D97F0036480E65A8EF894C938B42ED023A4B966D235479012594BAEA06E6E86DF73C9DFB000F748C8140AB49341B5952F5862EB73E8503B4125997384B11208972D1DA3D320064459B6D714A4151696A843B872626B051D219F8238BFE480182D93F70752319B8AAF7360494038BE5700F2E9B86E83812744989B4921469F8A4B41C682ED329203B00257A950BD5435B224E4699729CE58D3855293C62C44EEA5D2CF96B4063A10C8ACE2DEB53FA79B8A1E77F955A6A48B38119FA6B8106301A25849F9030C86A2889BC75C147C90D6525DC532745391E717C70DB15007423C06E8BAA23277FC896B757536C2BA5A2605397E015A84AB216635B2366C7BF1364CF87D3CC61A31A57A6949AF77AD5990ED54122D4082813754079765C999266C3E961E674C1F7D03F9D258C1976950A120E0E31CF6239362FF38E395935B5E29D40C5BFBBDC63C25855A372C3656C243AA135E8492F3890615CC75B3A25221DB72670E465E1B45128B131395B4F0AE3BB09E94965983FDF6A54AF087AE4F32DD7837AEBF893212306D8B6AC1765758466908A3A641F2962ECA97FE4A63D64804B5B259F2025197F0B0EA9996326D24736553ABF113594E122AAC2C62936C1BD75689E240CED9BCE098212067776023A4954376EAA342687195E548160835224283A4606207C6C939376030C91BC3FCD6466810C5FA361488824B35C693DD8FB56DE2412B86A9ADB28384F908B23ABBD28307CCF834D3CB29F3E1AAC65806F4084974CD7037E2B84F645733FD660D3C246076706856B2415B0A234A29A76532DD6D6320BD06AA459768FB067C7B28B8C89258C2354EC5926D23BA388C14E39A63F61D23D705B1B850C58804856934892DAA452007B2ED01C6196995C55C647F3F58BE2D27AF8845C2334AD27687A25E50BB6BC90058B181D7197C5331088B7AC1D18038AA9920145887247C805102B95F57235783A4847130E47566A60469575651F0137608395D010567B7866C8505E6DBB6F6728959C128C382414FA53C461850E7783CCA1B4265008642581A06BB0C410D2A791D0977669188C6231A4A3390DAC1B15243E41D57843C53E309A3DEE5BB0991A85109A716800866259054FE1CC59FB6A96A75C8503517EFB5517E8170376512A53C861FA35AC8C4B5E63756247042690BD67BB8E0C7C9E8F05C5CE48CAB0F1425E329072F87401634211241738C2CE97208C6A6AB609F03EF13387AC6C08A3FA61E53632677507711A25C1FA3454D86D7BFC75E668100D6A6A03086142275383E291097104356A0848724BD95C3CD89CCECE97421BDC67B0FC8AA0E0C2460B4AADD9033CFC60EF04AA6F39566E89793DDC0481109E532566D90525EDE57E8B756FDA7190BB89937DABBE2AF4239961CFDAD37F1E4B5BED5A4CB5637163840716A1CE2F2036975A640B6A7EF308690D66750CA05B9058772828BC458AA9CE47116EF459B01C292010B7449207EDE7AA38AB20F10280E316298E9C86B3B4B94E718B85798D5567C96531A6CF84BC806AB85E156A34447B15FA9FA5BBA5F1087189BB9D4561885B2547DBC5BC081C1A268A9EBEE5CB1D4147545044D11933F43871ADA5495C894793645B0BC472407BCDC5ECCE19F219C98532882381739B94E2366BAE2C543E68116BC30974149E59318DF3336204C22063E4481E688FE2634D790773E243A325AACA07AC65EED5BBB092B6371B519BC01067849E6BA3C5D9B4AF5D073BC84BB472C123F2C72C4B191C85405D63C148B368399ECCC42F208F62E75E14408BEB14101EE4249D2418C359AB05E5A3B60A5465637EC6A31419EAAB9458A285F684404C4A94425FF6806150C7111AD2A77C0616D45CAE9024BE5DE259FFD6C3C0E509DF484F2D219D5F3CB596BB763D4BA6C3521789FC840142A42D510F14EA44B3E9B573A49F9B0879CA5A5E0606639A7C67A7674124E2423339126FB019E00BBB5031A1AB9B3A71190459A16EBB0A196DD9CD5A152179082AFA9436B647A68111439DC325EA777BCA84ADDBD62FDFB61009A54FEB495A166BB35C9C426A678E6E2958BF52138F68711D623B41C7B4A97A241B17B3C37720FBF04BA3C175C96A4CED4C3FD0E4CFBB345A0CF48A7C0870E4353CA02B92A204A9C03A6287BA8E1CFA50B91C2E2674CF93382A72E8B9E0214504B97C18D60351F689392A8E44AA2C57DAAABE4CE52E3CDC2BB436DCBDECEBAE89BD2E392F0370092A66B4F02AC3FDAD8D8F210A271603D045F95EC94C2A38EF4985F2E72EDDF9EEA90CA3F0FDE3F9D49FA98B44BA6D37FC13524B7FF2435B88410255345590DA7870813873", + "E3C563F0E5A3E2A6FF16EC3630EA56BA17647ED1236BD957021549825E806DE8924E3AF298F5D3CF2D462E31082180D2C2964ED80D3E7D92E5227E01B9B740F1E2D111FB379AF7A92320EF8BAC44A2591C7438B7F916C1508C45106E2EE3629F28FD280D725C382D647C894E60C2B109843D5DB59ABFD52B4B98E86773CBC75C8989239C288A79AB1D6608FA6EF287BB0431391C0CFD73504AB24D10A2F8FA5F3C3F38D9BD48607889E160CAA09818830472038F9F6CC2F7AFDBC45870B434F421743E1E0FD019D5C41101D9DAC014472C4FEEF0A9EF980E7F276CC7F1E1513A64172428A4A091A4C9A6A009EE5621E37B179EBAAC0D122A8BF42AE861EA420473D2C8F9EF3F4EECA11AAF8863BC66310EE5233797134E849A01992149CDF637BE74F0292988572A38AC86959CB67DECF3B3C3BCCCF186F917476DEE06727EA819A51ED1EE6F3228F4A0322032759D74BEF9703BC185A59492A79A67109FD6786130AB0D41F346D59FEAB3F3FEEC1270904B1504FCF463E9B4B40FA9B5266582A8031F0B200954FD080E207C9B40608C499D49FF752D9D1A4FB5F91264085D9E1A4A1A1FC91B5C5B3DBFA5D1EF5FCDF289206F611610B948644CFF3632229AF44D2971E3FD85E88E6936DA82DDD8815EA1A5DD6DD3DFC03259F604FEFC59CD4F9FC6AB4E9D8001A747546455B9629CCDCF5C4058D57C20DB6C9EEBF7C4ECBF76784FC2C9A08B5414F02EE7C93A38201BDFF31068786FBF98654F0A32B188B891BC59D683E08BB2D6906594CD02B232DAE179BD5C10CA0F7323A0016876BD80AE16265AE3A96204665A01758FFA9EAD686D3BC22D92899633520437994D73EEAC9A2E55C1EBCC3D07229B2E5202DAC0285B2BD600437CFEFE98EC02B13977359FE4E51EA9FFCC287C88211BB220A3F0E52D5D97B547B2369CBBF46512DFC304D72EE1664C91BA5E75B2B1D089EA9C02BBB7E390FCB2EE60E56FCAFFC3E3FEEA01FD8D5212783BF71AA94BA94813325A0249E55BD4337B7BD662D6641DEA484962E04DB7B42522837991D1048E9785E3BC297B2106ACA4968DDC1D05BED81DCD061D21DCFDB82D79CE3853E8B2089A8FE150F3F34CA7BF540D8044D8E40CA3EFC66F1778EC0E131F922E28D8B62B4050042064360515B5A88032F82AC618C9356678CC77F3C4B3456C61462232D92094B29A139E975D1DBD2B2E5A8BD6AD7A3CB9EB9BC0C0144B2178EE709B2D8EFDE65FDF3630565FA83910C9C3CC179F4613467294FE778A33636AE26AA9C2EF2D0FF2D648D3F8E2B9E20D434EB8BE0AD4B57E87B92A6D3572D8DFCD38B2DF6D77C5C8C25612EB7A3E0C0791003DDDCFA723841749A6AB9A9A5AFB098E1A82390FEF7A0FED281D7DA116B830524B5B4319F93DB15081136B5B06F8FB289018B47BE3302C193C8236015CEAC96916E39E4E8C032398056DA8C57F7D0F0A0A88B8B91D5D4D2A37CC5F0B8935BA7FA7AC4A0E0D87ED501B6196B7A4014226667F0F0EBC221BAEB63C7947D8677BFD625403F99F74", + "F8497107CE0D948FF5BF6E039E3CC4EBFDF5E9409EF77171A1E4BB2165713A3B" + ); + yield return new + ( + MLKemAlgorithm.MLKem768, + "6A3A01EA24AE603A99613B63596360748386C8F33EDAD3AD33C5620DBB58FE81B76B960A28C8A893F7930F2583AB0431CB15B6D0EA97EE76045FECB2FEE09BE411B8AB827236C67D65C4B548A43999134D4FA3735629CFBF3314EC955194C8BDAE1B6B32635F27427DF0C8103639CBF7301C4C36B896E853C2377C5C155C9DEC611D1B6BBABB6777B6A95DA79B5456007B30CED6BB4547056C7B08B703A774114B036DC081BC896BED96C8F7C8BEC4EC945CB78E21503F04F849C053A9B7E1CA5E080325972FF9310B12B04BFDDA31AEE5C45E7BA024133BE2B7B389D22D3C9AB4CA34A31FA902571ABD0C267DC23157787B368F1352BA6A0F9D04187AD29CDCBC382DCACE8E31869CC2C7A55097AECC218FA68509D289833988EDC26B23B4CE26954A15041465A7287E372CC6213F7988768D105030DACD01B73B5F2145020287ADB92D63DB8D8E16A231618D4DD97851335C68811789428E8A8280519A81A215774B103981614224E35592647823E633E951646A1912721C0AD5BC21DE84734E285653B0858E5B325699B5E31C027B266E7E82C6473072A9E49B0B8C28BCD163ABCC7A3F3251601B4719F2894F1089FBB37F1F760079C6286525551BE7AC73E52926B28FF3F89A663043CC3C5FE2BC0312C3A0E1206583633F0747013C42A541E5CD53142D19D06B7E930CE1F68485D700BFAC9A71977C37A28CB11C703AA04FE533B58F6826ACC1AFBF25CB7B0A7890C427FE7069120315313C0A45C18C2EEA868243B4F46A03622C911A98ABBD7C2EA3305A5237AE76838350EC1512314A7CFB19549283CF2866F3FC3F429168A461034830BC4FCC2A7259BA6A49B256CA9066086A1BFA64712A7E5EF40BCC758B5A600C2717216839BEBEF900EDFBA4126C89047328A9849E80A596FA930D666099A9978085508F9AE8CD1A1325B4082457045A923410C84A0EF382BEA75420883C4E3E43183E8B9BB02A7030051526055910A835AF9053BFD66B378CB978AAB14B629F88839F3A4A7F985BCFEE440939359C7FF98B668202149045F68418466C45E76517F9F7389A683B47897A608A2F85800F7795BE75799DFD597057FA3F86C84CD52A4140758AE45B51F80262DD56337562A974B942DCD20EA2BC5C52F225DAF5A80BE0AED045A7E812819F646D28B0578D042C8B77C8341B46102BC881A738DDBB43411B43C41813C4C28D75400BAD4902ECE7C899FC7FEEE32C78D70165DBBDD139BA3EB2210EE3C1F6BC2B31C8C73B1A54657346C3D322B243AF797A93E7129B17FBCD3C7B9CE49216472BB6DF1B2F41BA4EC3813EE6DB3898F19643C38FFAF3880101B08DE8370ABAA82D91BFDE31B8F78CB85474A3BF06844A233E65884303CABDD1BB52F23C01512871A6FB50DCD3A2417140DAB019A11BC10176C5C83BB138CC2BB45369FB74995613CCF71426CC45536586A9ECEB63877494C4789E62B33BE19B87AC40357DE584F11B236E389B26A5578232478E56B798FA77E6366EC15046B38B4BEE0255FB6AC0B8B928F9F3849417B7C76A396D0B58DE16C709E58D5C523DCB6C7EF74C60960886926B4F5B472A7D2B419DB06592691B0F7299EE970B8ECA7F74B1258AD17C087C8EA0F1AA37C40C631CFC95ABCC465F6315C54C7531FF559F19B952406FF1BE2C2C", + "DD30BACFE52565345BDB2157888B5694438242E2A2792B5E3696C516F8AD1D893DA3FA1907ABC9F0E627866C30B1BCB4887C7291D0381F2976C690ACFA571184112F11251E38C61DE8E727198515FF2696BC8002000D0C1AD542360652EBBA33F5F8A037F50E146400BF12247B73A7045369272753B2DB9A5B13614CA446634B9513D3A050C155E879537CEC6E93634B3DC067DEDB1A6A378DC9674AF3F09A6726B346F5A1EE069C1356626D7126380745C7B065D5528735B36355A8260F3216DED3CDB1F6780B8BBFA409B67A266F097429C0E808D1F2479617AF9A05712E7731298455611A66C2584C8888B691F23B574A463FA8CDAD2802CB14BF83AA31D5D946ED55097A24CA024696148A3126DB4E69AB82EDC9024C4734FE182E45E8766732750ED443726A578E39484A90721A28CBB0E03DD72931405516F53001D57C4CA4EA2E171CC27AD896F2A8C6A5877C5338374DAC8DF4D762C1D97BC735430B33CF62BBC2D0A0A3FA8401B54C0BB77A46FFE5AD73FC2A5D285A1137052ED028DB79988A4323D0F8105C58AD9FB47BED3A60A8811FA2C55B187AC7DADCC42AC09B2EEA3609A06A68EB47B28025419B9C702BCAF06C38C86C7640629C89D7A486990D62433A66327A687A4CCCFBBEF4C0947966C991573592B78E54E7ABD5A9CD17D6930933936E049121C568CC013D415C23CBB2125F5A3B1FF58FA795B4E16B8C44A94FFCC344D035BDEDC45698A2A205414416A49F4E2A06281C9D254462C070AA8B7974180B3FAF81A7257034B7752EA315A1F4DC64418470EFBA37B228C0E5826C40D31519865D0DD07004B21B0D57872FBA2A00245C2702CF2C8AB91C5A5AF8F40614FBB1279C66C4F2405B4221EDBB8B35FC5EB65707559A29A04939C5990633680771D76E302616DA2A5384D875E5F2C3ACD4C96FA74CF88090B22540478161BBC14B8B6121607239056022EA3947EF661D72B12227889C2E1C266A7A60C014BE19E0328817104027475CBC78CE2C85012017EDDC0F7CEA11C8EA72AD3338498292BEEA4B8A7129D71B1927FAC2A6921DFB87C425F9CCBDE2BDD01C685E3CAE52425070C5C00EC8745FA538E4F96F72D89214E042F19734D7E57952D0833C72276CC93D9991A1AD99AE0CB5886FB83367C967CA65A7AFD022DF404DB0625FBF2C50F0D8812FE2BB1DB4351C7CCA96018A07A6AA62255655A59319AA9A0F130387AC5EB3BA4591A68130523A6D023F57D7801C71BF2237A17FB3590B240FB03037675A56CB85A68EC0C4FBEC98A1C534EAA4C1AFA1B7A012AE871C2EA6B34B3E661A90713C66A0A527676143CAB465205ED21B1E82050343B62CCBF875A2B13D752AA9007426D52661E6E1C42446B7FA632332498B53DC68D780264E1638BE1B24C6323BFF427030130A3091772988789CFC65369C98CF6A6BCFDC99CB477D0D120531C8AF46613228CC687DB38E984C269FA225E61B4B5EDC4246849CE2578BC7519881055D00295DFB560152F435E7A800F5E2BF2299A2BEBA0F0EA63D2B3550AAE2518EE80948E9961BB74D5B5B8C65C2C7C2229158B017B9250B2200809C8466387831C08B791FCA10D2DB3800429B35279310403566934BABE1776A3A01EA24AE603A99613B63596360748386C8F33EDAD3AD33C5620DBB58FE81B76B960A28C8A893F7930F2583AB0431CB15B6D0EA97EE76045FECB2FEE09BE411B8AB827236C67D65C4B548A43999134D4FA3735629CFBF3314EC955194C8BDAE1B6B32635F27427DF0C8103639CBF7301C4C36B896E853C2377C5C155C9DEC611D1B6BBABB6777B6A95DA79B5456007B30CED6BB4547056C7B08B703A774114B036DC081BC896BED96C8F7C8BEC4EC945CB78E21503F04F849C053A9B7E1CA5E080325972FF9310B12B04BFDDA31AEE5C45E7BA024133BE2B7B389D22D3C9AB4CA34A31FA902571ABD0C267DC23157787B368F1352BA6A0F9D04187AD29CDCBC382DCACE8E31869CC2C7A55097AECC218FA68509D289833988EDC26B23B4CE26954A15041465A7287E372CC6213F7988768D105030DACD01B73B5F2145020287ADB92D63DB8D8E16A231618D4DD97851335C68811789428E8A8280519A81A215774B103981614224E35592647823E633E951646A1912721C0AD5BC21DE84734E285653B0858E5B325699B5E31C027B266E7E82C6473072A9E49B0B8C28BCD163ABCC7A3F3251601B4719F2894F1089FBB37F1F760079C6286525551BE7AC73E52926B28FF3F89A663043CC3C5FE2BC0312C3A0E1206583633F0747013C42A541E5CD53142D19D06B7E930CE1F68485D700BFAC9A71977C37A28CB11C703AA04FE533B58F6826ACC1AFBF25CB7B0A7890C427FE7069120315313C0A45C18C2EEA868243B4F46A03622C911A98ABBD7C2EA3305A5237AE76838350EC1512314A7CFB19549283CF2866F3FC3F429168A461034830BC4FCC2A7259BA6A49B256CA9066086A1BFA64712A7E5EF40BCC758B5A600C2717216839BEBEF900EDFBA4126C89047328A9849E80A596FA930D666099A9978085508F9AE8CD1A1325B4082457045A923410C84A0EF382BEA75420883C4E3E43183E8B9BB02A7030051526055910A835AF9053BFD66B378CB978AAB14B629F88839F3A4A7F985BCFEE440939359C7FF98B668202149045F68418466C45E76517F9F7389A683B47897A608A2F85800F7795BE75799DFD597057FA3F86C84CD52A4140758AE45B51F80262DD56337562A974B942DCD20EA2BC5C52F225DAF5A80BE0AED045A7E812819F646D28B0578D042C8B77C8341B46102BC881A738DDBB43411B43C41813C4C28D75400BAD4902ECE7C899FC7FEEE32C78D70165DBBDD139BA3EB2210EE3C1F6BC2B31C8C73B1A54657346C3D322B243AF797A93E7129B17FBCD3C7B9CE49216472BB6DF1B2F41BA4EC3813EE6DB3898F19643C38FFAF3880101B08DE8370ABAA82D91BFDE31B8F78CB85474A3BF06844A233E65884303CABDD1BB52F23C01512871A6FB50DCD3A2417140DAB019A11BC10176C5C83BB138CC2BB45369FB74995613CCF71426CC45536586A9ECEB63877494C4789E62B33BE19B87AC40357DE584F11B236E389B26A5578232478E56B798FA77E6366EC15046B38B4BEE0255FB6AC0B8B928F9F3849417B7C76A396D0B58DE16C709E58D5C523DCB6C7EF74C60960886926B4F5B472A7D2B419DB06592691B0F7299EE970B8ECA7F74B1258AD17C087C8EA0F1AA37C40C631CFC95ABCC465F6315C54C7531FF559F19B952406FF1BE2C2C55A5817F1A9B11AAEC3112029860E6400D99E57DF796A8B775C8C5060D4C3DF45BA1405A293656507D39C8FC3990BD23E6735715792EFF440A9BEC79C7F5FDE9", + "690D3DA51B1D22BA09AA62B4FD6EADFB4C587C34FC434C62225B9D132DEDFA5774B4ADFA213EDB328DFD6056CEE8F96EC1454C85F8037021F22879FF0BD7FE1386BF272021522F774F10C4C9F7A53E18E3A7023DEA1C3BC8BC76EA8FCD2BE2442A655F2E34F3F102919B4C336B177B038A0CDE0A2A49787E89AB005999F1AC733A04B867D557AFEC7502368CF8DED96CDA58FD0C0426767AC2EDF808F8A03B45D72B30D354C9792FEF5213E7928399F09E2DE540F4826ED72F86C02637738ACF28B28CBC8D45D5A7A0F4AC5A1B7CDA2FE6AE3872C6985E61E259311D5201A540B4351DA0E794F3BBAAB916E2603633741A7878BF61B3B344715D6DCD614ECDE5EDEDAB3DCF4DB03582CF12B764179ED88FCF5FDB0A550522468E04A5FCB297EA78C1DC6DB4CB868F7B1D0B195A16CADB15C28DFE7D2ACD9C2399B6461ED22D000F3368E88BF12F32BFE6B749B4665978C297314DB35122C7D04738E38F7B4CD8246FD36B93624CDC7F0BB10FB482479EF1E1FFB2F85094C9806D160467832D604FF7945CE2D6BCDF15802BC2CECB90FA3F109987BBB377B4E0B092B64F712E3605B3B11E3377453538EB28406243C9C182858650F70CA9AAE1B8E00E3699D2C47038F2AF7076CA6C2330542FE680D79C463F60F80192F85F6BFA0AD455712840F0E25DFDE29CB98A68FD2EB4DAE3C536967D5C4615788AD70A5451ACC78A5419979EB35F83E2DEC8A9EF3DF19A73225832FC6EF76A19159E38DE1BD15B6931F4D47C25024AB2DFB0A800EDB9E070E1FB3628B8236AD227AC3F6603F1866C4CFD669F992C50C06C1986868330C4889B3A9F77DEBC702F3A6337A549B1F51FFBB7201B04287DFA6BF3144160DED6206B5AA1F9A03CC0D56FC53EE55C8CD9A23344BCFBE1439904A3FE6A225D3DC16BF0BDE2B53F90CC0064C4A7DA29E93A84585161D6B367063DF1AD2639E94F0F61455225AA72C294936293831B7F221D209D30317FE4D68507822BF667C8175F23ACDB14000715D26AB3303C46D2E9741F03A73C5FF80B50E2750744D747E295A6DC2D6B9C5D12F0D711267F46E61D25388A5AD57F8ED0EF9CF99311A6A14D0EC5AA5BD8046755921930406B786BB015F4C5B1326650CF8A6EA2FFA758C4F3250F235CF4A824807BFF10BF54910A610B1361B156980ABDE86D087FA133CABE34FC5EED86C3332B86A84742ABF33144B8B08E3E22C845A5E0C2ABD786DA7A7E01DEE4558365857B384CC3F398D74E157CCDBEBF8ABA82AB7804303ED27E280BF68AC3122F6881B3F75C0F5BBB69F6C02C4712FF8B9D1822686CBC441A4C81BB54DF79C90E32A2C5464C0453954DE231AA0D01A0FBB868B4467D1AB6035A9F0C85C1C4016F586B7B6E653689331949380A00CC8ABBB265089606F65E324FEE9AF4CDF02B1F6685AFAA05E2DC9AA17AF7E8131D1F1E3D2FFDB9592C9C57CCDD619274D547FE2285A8989DE7926C654DCAED5613CB4DD4A2E0BBF9BAA7DA1A0F7628C924927EC3C339A38E73C219CC79EDB4904F97", + "8B6AA77088CC998C2E6B42ACA57DBF3FAB786DFF66ACB017B2ACB48FDBC73D07" + ); + yield return new + ( + MLKemAlgorithm.MLKem768, + "11D14D803290BB20BD026906B869C1B8780E3ED23F3F4ABDBDD3873BE9191CB67E8C5463B3A21C5B6C43699450C6B4CA2A30249EBA1D5133887E9A4F005C4724D46533A4991A12AA905588A484471F76AA7F38512ED20B4EEC05DB8734E340799AC23546D9C8142C276A46B58874AC6F5641C6DB2A2981C45C310E2171C3D6B793CF4B2B6F0B30E012C2FF3234D07C9105D9673ED3C9433918F70738E10A9F3ED7C4CF506B1B60501BC833BFA3A001C36C9FBB9D9B118CB444B575A768F54379E8C25E4883A209E3B68E141679349CAD62771A0B855F7722C27BBFE4B54F5E553DC4485E18A08598C32AE057C2A241273F116366FA943039B19F0B817CE6691533120A60ACCD62ACF6B5868BE05CDC9A08EF47CC1CB3587A82B699334254F6796C538465120824BB2FAB3172AAB904F9768693306301627F87382E8D77B3D69A22CF878E7998B3226A14EC19AFC88445A7243FCF8308DC8B351D402AFF98B14840ADBBF50F49A14F018A95E3871CF7C75EBC1C26717C20F8BBC87CD2900DD6518129789CF83D9FB0664B966BF394BF213A0F2FD7C0DB493A13A2B8B5ACC5B18929CA325F1C51B037148CA0E8A401587D570B067FD14B52620D16E4BBB74C2EF1E7B4CD74B15DFB08996AB83D8396DA99049477450C93B24C0530AD5B2E9A305EC6B63A09954D1E961B2052A6FA49C4A55CCA4DA1C4711383552CCEA53CC572B6481686B71F12325C03809A36C02BC0835D28768D42C942E97A9AF1C007312FC0560EE1010938E146FC9C07A851C7E07B655EA2A85E777DB3526F0882AC8B011879A015CBCC81F2BA22193640A5A045D5B650250992995CAC5E9058E8EA5ED1D41F8F479E4509025E3CBE83F567E2932D2BF33AF773C5BEDB8EBA9A2240C530A7EB61380AB5AEA96D1F04AFCD0ACA9F04438C743CDBA128F7F70B7C7901D98616B6C49C5CF557326552F9B1CF8FF019BB38CF527B84AF4055EC180CCD5066CE96CA82121E0CCC3C61232B10C532359ACC2406CEE37945DA11CCB0A69102AA510E55195CEBBDCD77705D2BBE77F37B8657655048ACF06519B47B2FE469891C8303939A3F4B68B9516B38430A6216ACCEEED049FAA44FE2D17D6FD15797630CAA001595CCB3934195B1365263D861BF4B27F1C70A500BBD82054B8192417ED0626F077AE670B23CA37F8AE64B8DE49A3A3A70C081CF581041846861050088FAE35F44037549E5244F385B88997EE5FA70094B4FF50B531C87AEF1308AF91731056742F96967C2206B076A1FB219C243A74AA0E607CFEB9604D04ADCA3904DC397E1777D3B58197EC54D37795CCBB4CAF23A5A546672B0C2283AE7AA5C914009A511EDA293CE06AF182A606C23A5EE4458674170B20712C58C8CA87CAD4A8739B1E32092F9AFA24B8DE6CA70040AA769F9258AD144E1CA8D635031FA70A710B3B717FB65304C7B23C553067688C8658F94154CE79083B9A1BDBCC335A525912AE0466AA9B9E3D926C21A25FACC56BB738949366CDDA31CF38551E104BAD04C3CD3866DF028AB7C067AEBA10E751C534ED886FB5C4BFA0051FA7B23D50B80C1A84851847D427009767796592A79957B25806A613E39078CA8C30EE18688704FAFE5879DF63A3E78FEABF45823C3A23E8A4FA58FFACA18FEE9253CBFD62A05FF71CC07", + "195006A3550B231C8348E6B3B5B386E9E3108AEBBC8F83630606586EC28635E58878809A5A53363214AA48C3508C32929090280C366CBCE2971332C96F05551F06814F340B5490BE545448EA603BDB945B5B778130CA72AD490E3FDCCD1904487E1284EE392941970D44CA314F38BF6A22414192A1372536CF1C559A48A5A89011D935781CC54E6BD43F8CD3A952C6386265971212C21D8B6BF0CC0B72D560DBB79C0092BC0596BA5D5B70A1C48C7E474163B00CDE389ADC881BD58075C5C43D22A28E1EC51023B27024249C3382A25E26C56DD651E92B45BCB96F8B41C671C4730847253A15C1C2061A055603397C394157570848A88D22C4B1FA0808F65CF47A7CB5B06E149900A1DC9E8C4C58BE1B082AB3B99AC34EEF855216F4B4D9D276A687636DA8938056AFB764C554D07A9A7241AFF51B052A475E37521390906A241B73F71F5E8913357C8257392B17430CF76154AB6CAA1AA255771954CA3CAF731748D870A99AA4097183BE1013C9BFC7CD78B8C77C4412D69A518BE91C2DBC72C2656A2FB18231B958714513C51C71CC002139936F64B8C6879C78BEA352AC82691041C526CC97BE790D07DA9ADE6B4DB28953A233B0B7F0AE0E08AEC82256B70A51BF893C1D643E6629011537B845050257184E36B3A90B008382528F0FE268D36453B08894115B3C10617F4A8A3C63E748AFF07B60B76179572DEC958531DB5C903C2EE826C18FCC40636B28E5B37C0B47349C4409C599614D1B5E664B12B95B71C46A2DC76979B23B889673B0CB860480598984A78BDDEC5DBDDB8463E7941515B804159D46E8B51E24139D557A5E8450EB84A3898153568609D382287651003528237325B291D28BB4356AFEF1A903D9006BB24F9AFA4CE0E4A490AC32FEE2475A864E2B74BCBF780827CA2F94D855E0117A6444BB31B4383B2566B2140825025375AC17DA535031456E5EF95CF7E95355D11C7E3C113E589342AACCCFE5761DC21837BB8E51BA9415C2AF3F352B5AD57CD9288DE0643E0EE75D9019C3E7C8BDA6B6645BE63E206925554B34B95B34D33C05DB5970FE016A6A51C86051B6C364A80E832E0156AD688A42E73A6D20420CDFDBBA7B70C40436668BDAB6A014CA920B2A4C34595C187B20D430851265C3C858213C57B29C01AD822373A231598633FB027EABF40C7C15884813AB59A39D18735E64F4622B384C73D433C1505183249044B61857846F9A54C3D3A213FAF2CD9A33194648375FAA08A05AB96E52464B91083E60C7366981F8C0181CB8B4A6342A08614A4123285C8595EB1B1F2B1398EE670393117A26103B41C7C7282166B7E49F745A936981AE9F0BC73CD74F97F6AB133250DC081DF88B1E4771A39CF3BE8F64CE721B5A828528289AA5D4EC6FF0463191D3BC6221124B52C405E88E96EAB49B435BE9415A91A68117C5650E53613A78AB2B0915A4FACA6545B9628999A3A46AC5855FF2406613101B36A13AC31B55E8D118F4056074C78275C80D57D9798819B3F8368F19826A728A9CF05CC637690BC971A86186A97A2889F976BB4654A778258D91D37E2E7B13B584817B6C22AF49207997BABAABA5B7F8665A710574A22EA42B4736E720E57C470A274211D14D803290BB20BD026906B869C1B8780E3ED23F3F4ABDBDD3873BE9191CB67E8C5463B3A21C5B6C43699450C6B4CA2A30249EBA1D5133887E9A4F005C4724D46533A4991A12AA905588A484471F76AA7F38512ED20B4EEC05DB8734E340799AC23546D9C8142C276A46B58874AC6F5641C6DB2A2981C45C310E2171C3D6B793CF4B2B6F0B30E012C2FF3234D07C9105D9673ED3C9433918F70738E10A9F3ED7C4CF506B1B60501BC833BFA3A001C36C9FBB9D9B118CB444B575A768F54379E8C25E4883A209E3B68E141679349CAD62771A0B855F7722C27BBFE4B54F5E553DC4485E18A08598C32AE057C2A241273F116366FA943039B19F0B817CE6691533120A60ACCD62ACF6B5868BE05CDC9A08EF47CC1CB3587A82B699334254F6796C538465120824BB2FAB3172AAB904F9768693306301627F87382E8D77B3D69A22CF878E7998B3226A14EC19AFC88445A7243FCF8308DC8B351D402AFF98B14840ADBBF50F49A14F018A95E3871CF7C75EBC1C26717C20F8BBC87CD2900DD6518129789CF83D9FB0664B966BF394BF213A0F2FD7C0DB493A13A2B8B5ACC5B18929CA325F1C51B037148CA0E8A401587D570B067FD14B52620D16E4BBB74C2EF1E7B4CD74B15DFB08996AB83D8396DA99049477450C93B24C0530AD5B2E9A305EC6B63A09954D1E961B2052A6FA49C4A55CCA4DA1C4711383552CCEA53CC572B6481686B71F12325C03809A36C02BC0835D28768D42C942E97A9AF1C007312FC0560EE1010938E146FC9C07A851C7E07B655EA2A85E777DB3526F0882AC8B011879A015CBCC81F2BA22193640A5A045D5B650250992995CAC5E9058E8EA5ED1D41F8F479E4509025E3CBE83F567E2932D2BF33AF773C5BEDB8EBA9A2240C530A7EB61380AB5AEA96D1F04AFCD0ACA9F04438C743CDBA128F7F70B7C7901D98616B6C49C5CF557326552F9B1CF8FF019BB38CF527B84AF4055EC180CCD5066CE96CA82121E0CCC3C61232B10C532359ACC2406CEE37945DA11CCB0A69102AA510E55195CEBBDCD77705D2BBE77F37B8657655048ACF06519B47B2FE469891C8303939A3F4B68B9516B38430A6216ACCEEED049FAA44FE2D17D6FD15797630CAA001595CCB3934195B1365263D861BF4B27F1C70A500BBD82054B8192417ED0626F077AE670B23CA37F8AE64B8DE49A3A3A70C081CF581041846861050088FAE35F44037549E5244F385B88997EE5FA70094B4FF50B531C87AEF1308AF91731056742F96967C2206B076A1FB219C243A74AA0E607CFEB9604D04ADCA3904DC397E1777D3B58197EC54D37795CCBB4CAF23A5A546672B0C2283AE7AA5C914009A511EDA293CE06AF182A606C23A5EE4458674170B20712C58C8CA87CAD4A8739B1E32092F9AFA24B8DE6CA70040AA769F9258AD144E1CA8D635031FA70A710B3B717FB65304C7B23C553067688C8658F94154CE79083B9A1BDBCC335A525912AE0466AA9B9E3D926C21A25FACC56BB738949366CDDA31CF38551E104BAD04C3CD3866DF028AB7C067AEBA10E751C534ED886FB5C4BFA0051FA7B23D50B80C1A84851847D427009767796592A79957B25806A613E39078CA8C30EE18688704FAFE5879DF63A3E78FEABF45823C3A23E8A4FA58FFACA18FEE9253CBFD62A05FF71CC07B568CB4D837941CB1ECAE7D1816414BD4C3087042FDE3920616002F9CC6F94FFE4F7E02022A7002586990349F68FB68A93A302E8C21C6A385719FD8987E9B902", + "6618487F983BA7883B55EF192AA5AB0132F0489334F6756286643E4C1C33CCC2C395B90BE43202FC5E00073A35C3D08C378FCAB6E2F0CE0FCCDF4F684B55DAF3032818712E426F3E1F57BBE813D67E515E7C343673464322E7B63E30604A10156D1F79ECC57D05BDC55EEB7AF23C9902EFD4F3BBE2A79A1A9CB421D0158297F5840D02AD286C40D607059D3C926647BE162B333973D6F89B6CE4028C7B3482EC6BB2A6FCB97EF59BC1556D2940675C587EB24462E7D0D0584C6FC2E9FDBAE3A7BBE6CA74D6D3BEF8E05F308A7F6A51AC1AA9556ED7E8A7529994C41B34F36314CDF0AD9F07E1ECE10214CFBFA656D1D492810A66ECEFAC960D1377DD1DDA18BFDE0E8363A161B621BA8C37AF3EEA65491F40639823B555134D92DD622A367EF7CC5408F2CE18EF9B170BA2FC62004FB76B2545A54F68450CBD9221CC89A6413B0B1A80D3C6C039DBD1EEF85F4EDB018CAAD07CD17E33B44CE418368000FC000A10F82CA4F0EB860B46CE1BD10CB706DE0263660EB0BCFA0737700DE36E2C2F349AB8DEEE35DAAA5B983215D9E8B801370B93FD116A404BAB783C6E37321C8AB86EED41072315CE271DD4B52BBA7D968FEA1ED693BCEACAF6E20F3F4AA9FCBAB6E7D16D3CBF35B6CEA86CF6A1A88AFE50AB490F35936131F45425B94AAC5A83D16164D348089820E7ADF5253213293D05DA970A1B40506C76E65EF4A59345D00DA5461D4E188C9EEF0DAB41E7684E31F3E20ADC71D6FFD89552931FC634BF91F465E38DBCAE1FBB491AFBF1530DAEED2C68984435262280E831C1E9C9F81AA0C80D91BD57ECC02A1873A27EC3F09E99656687997B9E05460A061F3920572078ECF4BF32E6C42E06AD27EA06425D09F58907ECAE51834864ACAD3FAB372AFC0E1A789A1E98C27D523C2F5068E88E5372FCC8FBF4E5E7ED766C561CFEEC2B6D1AF29607CA7C4BCA48365A15B0C3C6BA585608DC6898FCF4C14414351C8AD2AB6FAE6C028B883E27E968A27ED79367EDBA6B1155A3010D42A77CA7EC2F2525936648671D95011B5BF019BB5466C881AEF38C75E1D6CF775AB2336CCEF8346D6B55B58F7F63026E9C9DC38A0E6E2BD550DB4CACF6433DAD6294EEE825928DC71ED003A6859C16CDE0835FBEEA446394424FD517E94A7D3730EC9029357A54A4ED34EB62A94A58D99097C5161CE5CBC6CE312AA625A0EF83EC51902A4959CBCD9A056DADDF7E2B26036453BE57984C65D68859C00DF8E1C1701595CA2DD5CBE3FF3150C67FCCFE765DFEB2A20B7BF1732FD083C14346FF2F7501DAAF6F6B77954A59F7389A7469F71248A2C70C02EB0533A099167713180A74EF90D5EF3F672BAF5C47735CDF9A025D114A062D3020ED12F0EE1C1AFACDBDBF08A3E5473ACD47C8D45B3F250560337BA924EEED08D5D6BD8AD684ABD18B442F8AF9E125F2486CEB81C950080505A0446995B79606D4706C066C6ADE8EBCDADA3D6227890DB24DC7D1A33BBCD1722F8FA7A6B5E8CC37971FAD3F878D2CE215A055779FF5522E9CBC95B7", + "29759A642C4D0267BD5D96C81449F6F9B315FAA45C1D5E117362D4F096D5276E" + ); + yield return new + ( + MLKemAlgorithm.MLKem768, + "BE0412D99A23CB207074F8A203A4421678ACFA3A225FA5C560055E8D380187EC6845DA3BD3611FD6E917DEE3CF2830C52C026BBA8A6A31578B942484F0079E88B2AC05D7C453D73D3716BEE80C698A323D2D5331B046B86AE007AD40CCE3927A75F4894432C7D235B4B6610A792920D5F0CBEA389235784EA91BA02BFBA238A79FA2ACB6B2A91DBA4BCD0678796D0BB4357B4BDD849762F4A7CBC69D163C7874C9ADC92B01EAE8AE616461CC89ADF41C415E484B94BA43FCE7AF7B520A598B35429809C109CD7C048B9C67C70124B597C1979A7A31B7156CEEF849C720B39406A32D1B639D18A1D0E462699181B9523FFF361AC995BF1127A4E5046C32F1A1E102CDFC431B060975A7437EB765BFE9A486CE6A52E3E33CEA47766EAA9BAFC819F248B0520313EDEB524CC6BE7771C75E96AA1096507CB18E9B101CBC21132A7337D78C0684E07C3AB8260E2070A3825EBC625F8851CC3E653011DB01DB07CC6B350A68652E31AB630FD373B75A1099A72C35441B9B6127B99469F95B503C663C9B3634A212936B3023FB4B50E8186619B00925639F52453979DB24D2B8CAACD61094D1B14C9597DF53339105C1A6D89BD6D626BD6C5D0E1BABF903CA8B4B48420A137B729A2EBAB17FB434EE258EA5F4CF9B9B1F58E85E343292981C0D02C4003F52B2F37CB3E7CA65AEB8A7F2EAC05634457581A9ECDC487223691263B696F8BD1D685770256AEA5A94DB60AE05A501835848E2F8CE8BD7CF5D1365E6120E18D456366B19E9F1ADE4C552050A02CEA89B8F99BF89B36C08232E13F79A25310934E23FA4ACA724761E12B32322F2744D93A6E4B0997B019C6857952369035F284D60D70581C593BF4B5749987B2E569941860E1619AD1D524469E987B7261F2274739699935291656D114525400984865B91895EC6C39EC54925BE2581D24A62D7B2785C2C697FD61C14C28D1A9568C9C331E3D749BA6597D9BC94CF391A7E3AA57C52C7ACBA8A6A85941BDC59CF57CA46336B25FB9BA93CCF8719A0057969A764399EF2CC3A81AA1C4534E195151389432BB43EC54A2DB2DAAEE068921A6A275333AF3A66C22E924C9CCBCD298663D6C4048BB09E8785387F8A291B3C15E72CAC44C6360EAB290F633FAAF4B023D000B03371EC885EBEE4684ED39A3BD03A390A0F7FC72F5E9B8574A23098404E7F4620C7A8411370B2AD8813DCC91011670FD3A29C088303725CB2425C783AE71539C75F96C1B1B395BD936C118B0BCA994627F32A6B53A187884453CAC606C39B81937670FA915A36F44FDF00D0AF0CBABA707A9FCC3672123D4EDBC1E7F30692400CE8E83E198A5CB692CED4363D7781095E12961BD27AFE1948C8F7259E336A2531082A2978C72BC67AD30BCA086C51A7BCD57B7B15F64E332C1F91AB6015105893917102530459C218DEEB58F5DC9DA5262B7D8A3159B43154F8597E5C57CF37400A2C560081B098DC2C20F6B5CCECC6BCF5B96184B0F7475076317C2EE5482ED83FE058108F762958E610041963937930C3AA3E6985423A33A07E77613F7236F0D9911AF49344A15D77C02A68F19C661704EF515871659F050251BF4CA9074A1A2B1A028FCB92E8053DFCAA319334C6443FDC1F8EADE4EF0C36949A1D36B440747C8D27DEF2FE62C033D6C17CBCC8C6", + "A7F68B43898F7383B09F0C6EE0D97377D454D528132DA90AC55819A461B58424BB95C7C00A246F04F8B03D3C9D62389AC2B45DD6D43F32072C86E03812909650C52A0104A42696C5E1F389EE4A8775A9A063737A5AB41D8C0C0B8C49C822D7351C1A63BE677D49018CF18311775926746520D650C1C31C0BDB6B570C96BA6B06915815C0FCF6B32F583E80C2B7A84B805ACA39F676426A463E59D6C904042761833CD4C0C0336B00D7E158DC774C5C58BD71458C7C74459682245A03B3C8B8522B7448C3A98432C48495E51E7B401EAA8669707C16F36B72FF21623838B31B496D56B12C0747587325A59509379D2706670C573F85ACA0F426119254D5519D759232C5087B84520F2459148DC6A86184662BC368BC2C83FE0CA7BE156C67C05025A1161BD1380DA39BCA2C99EF727B4DD90D99C21209B573803953129C4DC82A279ACA0A73833C5BE189187546519C2E17EA895CEC1EA7D46594297FF43CBFB7D54466B21F1DD4B72116C10B6198553AA0273CC6F38CA9F9011985012AB4F44C7DC13B00A10F646456D9B29CFDC368FA610C49F1BBF75B5759480A43CACAF99C8BBCB5873CE1CC0D091F6282CB6D1A9FC34459AD0333C88A1C7FA3132DD2B415F809235A101162120CE0BB53C435EED595E01273622CB6A33222477634104A64909A2CA19956D0E0CBDC6A8A611128DF161217856737100205E1B1E9EC844C447E4A4BC538157D5EF37A81F3BFC0F347CF14BD3F75C18F53A777CB0D381B0AECCCABE4005515C911A2C4C7123447DFC93964262FF05A45D969551240BAE60B41ED698AF8E5193BF409862759599C598AC63460F991D47A18A7E7A101964E756603D3A4747A10179CD77FFC1614B5B15D028B7F5794BF7E46B09DF68EEA6744ED117EB241B59095177314194E6C9BFB3049AF1CCE267880E810A855BC5A30177996C22CEBFB58A93331395C52C0809813A2600EB2CE358473DD9A25D8C149F515A5CE10335E0A716D1A09AA817ED6959E18B79ABA93A7CA25562E458A294B767AC5BC860756E2393DAF0507F185C7DE839D2E70885885973B561A660A8E497C0999F99D6C7C66AFA2C1A098A5088685F330969B3526D09758CC8964E3B543DDA6177312507730AEB98C3EA4E4C9478499DD676D2634A7BD69BC2FF8CAEC434BE2F58428334B4014255C4654BCC3A46B737E486C424DC019EF071FDFC817AB7B35362313D7787C73EA9B411CBABB5526441999C6E9ACDBD581987A4A88A421FBF42691A36629A37E7ACA126A7BC68A9BBDCF270F2EFC8E12C328B39A6C80D24496931C012769559A8042F0C2B81158AD77493949987295947AB5CA8EB13B2D668990291CCDD0703FC046C38301CFC350EAB92B9307A685D9BC43E4105F8BB286745E60A4A37E6966F2F7B558F8427DC17A122143C12271A276A0C6D28FF8410C236B68C8CC75D46B403F430716192A47FC7A8BC2CD11528870F7A5AB52A752609D42A05250538E1CC07B4E278CF2977D14F9BB1BA701D771915ED65903BB5CDBC5C1FCFA1D4B04A43AA4B48D946A5B124E3789AF2C34BBAD31A17839653E849E2B917230824887193568FAAC42F533CDF4B31009950EDB065CDC498536A3101876BE0412D99A23CB207074F8A203A4421678ACFA3A225FA5C560055E8D380187EC6845DA3BD3611FD6E917DEE3CF2830C52C026BBA8A6A31578B942484F0079E88B2AC05D7C453D73D3716BEE80C698A323D2D5331B046B86AE007AD40CCE3927A75F4894432C7D235B4B6610A792920D5F0CBEA389235784EA91BA02BFBA238A79FA2ACB6B2A91DBA4BCD0678796D0BB4357B4BDD849762F4A7CBC69D163C7874C9ADC92B01EAE8AE616461CC89ADF41C415E484B94BA43FCE7AF7B520A598B35429809C109CD7C048B9C67C70124B597C1979A7A31B7156CEEF849C720B39406A32D1B639D18A1D0E462699181B9523FFF361AC995BF1127A4E5046C32F1A1E102CDFC431B060975A7437EB765BFE9A486CE6A52E3E33CEA47766EAA9BAFC819F248B0520313EDEB524CC6BE7771C75E96AA1096507CB18E9B101CBC21132A7337D78C0684E07C3AB8260E2070A3825EBC625F8851CC3E653011DB01DB07CC6B350A68652E31AB630FD373B75A1099A72C35441B9B6127B99469F95B503C663C9B3634A212936B3023FB4B50E8186619B00925639F52453979DB24D2B8CAACD61094D1B14C9597DF53339105C1A6D89BD6D626BD6C5D0E1BABF903CA8B4B48420A137B729A2EBAB17FB434EE258EA5F4CF9B9B1F58E85E343292981C0D02C4003F52B2F37CB3E7CA65AEB8A7F2EAC05634457581A9ECDC487223691263B696F8BD1D685770256AEA5A94DB60AE05A501835848E2F8CE8BD7CF5D1365E6120E18D456366B19E9F1ADE4C552050A02CEA89B8F99BF89B36C08232E13F79A25310934E23FA4ACA724761E12B32322F2744D93A6E4B0997B019C6857952369035F284D60D70581C593BF4B5749987B2E569941860E1619AD1D524469E987B7261F2274739699935291656D114525400984865B91895EC6C39EC54925BE2581D24A62D7B2785C2C697FD61C14C28D1A9568C9C331E3D749BA6597D9BC94CF391A7E3AA57C52C7ACBA8A6A85941BDC59CF57CA46336B25FB9BA93CCF8719A0057969A764399EF2CC3A81AA1C4534E195151389432BB43EC54A2DB2DAAEE068921A6A275333AF3A66C22E924C9CCBCD298663D6C4048BB09E8785387F8A291B3C15E72CAC44C6360EAB290F633FAAF4B023D000B03371EC885EBEE4684ED39A3BD03A390A0F7FC72F5E9B8574A23098404E7F4620C7A8411370B2AD8813DCC91011670FD3A29C088303725CB2425C783AE71539C75F96C1B1B395BD936C118B0BCA994627F32A6B53A187884453CAC606C39B81937670FA915A36F44FDF00D0AF0CBABA707A9FCC3672123D4EDBC1E7F30692400CE8E83E198A5CB692CED4363D7781095E12961BD27AFE1948C8F7259E336A2531082A2978C72BC67AD30BCA086C51A7BCD57B7B15F64E332C1F91AB6015105893917102530459C218DEEB58F5DC9DA5262B7D8A3159B43154F8597E5C57CF37400A2C560081B098DC2C20F6B5CCECC6BCF5B96184B0F7475076317C2EE5482ED83FE058108F762958E610041963937930C3AA3E6985423A33A07E77613F7236F0D9911AF49344A15D77C02A68F19C661704EF515871659F050251BF4CA9074A1A2B1A028FCB92E8053DFCAA319334C6443FDC1F8EADE4EF0C36949A1D36B440747C8D27DEF2FE62C033D6C17CBCC8C60DF10A55B73E721350FF5FFDF8C9717103B3F242F12FCF292DE0CE75194E2E59678218BE4EAA47762D1ABE76C755C76249BC0DEA1C5C1625531BD1F86FA0AFDA", + "6C69EB30D9636EBA9EE14BC92EE730720D39E189AE3ABD96367580845A82F27C6C85F7135BC2471553CF1B0E0F092D87AEE9AE24649D6BC910A6C6B432F20993E562C5A1777BD801A7F1C05FD3A9E8DF57A187CF2637F99C6E24B5DCEAA64DB892796803DE9C1B6EB9E297440F7051D668F4781764F84CE499D6E7F6E4086C1F9B862260630E1B3E6C4BE52EC4FD99670A345659E4D865E5DBFD19D6412B4C9D31003D36EB9A1DE2ECD3A495B9E5A44D51BF85610EA867C9F4F1F09E10667A4919207628B2FD91330BADFD44CF491CADA6FA9AECDE5E20CE8AECC2986647F2656869E6201D851AC8176D98DCADC5ABD396B0C4B468871D0EB9332C264AC7550CBA62F77655110C4D15DA73A641F67A7821D7C7EA81CD4DD1BEFC5CC056883E74EB8DC985CA193ABEB30865A59C86167DFB51F96891D604577572D61623950D5CBC20F2752E6C65662950F7D69C4E6D883830326539DBEE1A1E683D74E1B261AD1D825D57FABC3512A405B172BE7AC22479E4D2F834009337726751CA617A95A6E915E50755FD644D600AB670EEB5F1CF097CC521A7EFE8A712E52FC91634EF0A3B87B91370444661674D9F1D0766DE59CEDC70CE0E78EC062F7A50DFA575897BB4A758FC7D49A92C6CDCA5020C0408A7830106529CCD6CBED34B0D5CA2AB68F27CA869ACCFF363BD546CD6EB6ED3589BBAE0D7E3101C71D63220140CE0146DC2A038B4C32749A4B99C3D9666688582984FBCC82F79FEF746180D05B8574FC42BE26E35961E01F2EB634CAC23BDA5D798C7264223524A040C9EF7D42673C7F6B0F2611467580EAAD9FFCAE0291962A98EC23C7351D620EA02723A6493E6354ABE0373FBC77DCDD022025F8C7F94C3476A0E400AA7414F6E50584E14B7DE84968F47083CB228924551191FA1031FEE39CF9A0494A18E34FE269F980A15594A6F68499FB01BCED9DAD187DB29842D928755F618D08B3F44A243257D7EBECADE361D47758A3E3B6E06601E4F409D2208F36397300978FE8173082851DEC328325BA05676848B9198E46966EEFDE2DC72417841E82F9848FFF6BE528F147648F881CF9718E6B1F7E0E20C6A1B37C5EED42DC6B982CB2232802CB71E83123DB105E6DD068BCBBDFA964C9955B2D93B7776EEBA03C5650C631D8F05AD84AD7D8190ACFFBA4977607AB8CB19788BDC7323A7A1D91B7AF8BE6A4386ADB47BEA4B4D93C01665CD605D5677B9A2B75A7BEE386FB1DABA09ED209915616BC544167B97C9E23DE77B757D5B98E63CCA9051B6D882313B4477D10B04128E6FBA7E1EAE23FBFB64C8D091EE233FCDEE91A0EA195CE511C3DF4B24C17B9D36389EF5CEB3BEE6D9A50ED35E3BB72E95040851A4AD2910CE6EC35A17AD1715DA7BD121190876203457836838B0415A53F62F9A6C4CB2B1B8E811FD78023FB5A119214D192B813E9B82B82574D36A5DFB1EA9A03D20ED2DF12A04944FB9BA283E0B290BA7370B5098A328AA70A1455CF166EC6A6DDC0704FCDE258E1F7363B4A46B4AD1B6E749D7CB8F", + "F5D303C2E38227359BA4A64727A9424DE88D41EEC961697385529C4587980D62" ); yield return new ( MLKemAlgorithm.MLKem768, - "DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D1602", - "21015917953F3926871D0BB9BF7802978493FF5A24D684CDEE1B76681902FC8A9B63283C362C33FDB2385419462F4AAF9C6A9588F06A5FE52F2BC923F87123B0099D0A2B456D350B21050F14BA0EC2A56974C9A1403518330C809DF69966D55FBFB70DA27136DE5793F7E73C71ABA60A5906CD36C5653A2BECACC4459756D9E37E14E6587F40389C0895E94BC5C105C4A394098F3A5F27EBB0D4E5B338466F1C964F79322E0CC9AC17B68BD6D20FE77996A740ABF95790B69168320C320BA6602B9624CBF12C84F549E6C40CCFEABD939A934E46A8C63CB627E499D9936C8BE3927294523179224307872F9B8667B175349BA867CABC3DAC47A48A46BC001B647B7AE03878F55A7029894173039D8D1C1F9F49BE12E88743DC709F101280662EE604CB25E75215A570D3FA03A88867E8C4A84F0351AE051F90E36441366714545236CA643BD8B85FA947ECF4A536C13DD7CC6BE7485405C0CC204B91244B364E7A33A60494683A99F5E3C21BF57379061AACA63E569C0E82164633A691BE803B2CD9464996C050323C21080E8C0822730B904FFA7A656C1B568708168A4CB1F54377A02542C42694BBCC38B4CC27F7B735418346FCC8D09B52E89B8F88627BDFF73A87A07B58299AFB321B0BFB1228E53DEB899AE7582066520CC85276A0236276738B58231FC610C3C40B326C4763AFA309435B05AF1C66E84C49430B98F7D4A76A843A627693BE3A67F57C20140B94ED694A1F671C0FD378DA3CAFEED30E5C366C3509AB1E14AB1E08D029A18BE1200D1A8916A1F011B7D0A9A47860F0B09DF996939D2377BC53B7E7CBC3A9517C31A78BFA724B6DE96EE101782C0641E2EA187375B8E5579426995BAF9C30466C4160780F8900867DA89944B1AAB84BAA7F987ACF2AAD97ECA9C222BF2C34BA5F8BBBDEC2C434E43828696FC38903F4C3B7DDE727E1D36A71F9BDBC71C878A3399D346669924E1C3CC2B2AA0DB08A0F30FA703DC308E54857E4142846F9235A48538E291D683409E25CC5AD1C56B690039DF5AEEA596F52AC991E1B3D16E809BFB723A7004A0DB59F0B40885189C88D4CBAEF3ACA2951314ED90789E366EEE8AEEC84798FE931CBB3A42E847870ACC06B3885C0EB2DDE149DD802C1F32953AC20CB87899C0855B2E1D6B8B5F6929D3B9603C73BAE5C528509AC1FDB34FAB2C63773C44195010CE80A229696CE075ED4409A0D0CAA966B20D6C356C4F44272E1501B897159D544F34B7C3B0280D7FC54E223AD865307BCB36CA13729FBD36DB285CF5650C7FD451CD8B305280338C7460385464672D73C5D30A4301A611DE6751C76CFA0BC08D8958F9A170C6D0ABD75007327E891A874181BA87A9260C14378068F183EA9E1CBE1E571530856D7118D9F1AADE546691BF328E5460B114A7DE834B2B218B22BD4C83A3A4580B2C59B325B1BC68231C3732F9AB666C726BC4471E204800C27783DC8BCF6B6315FA8ACE005CCCEC92116D7B34490880452A82098B692552279609D073CB0FD58C82CA888673A093F4696F7A4CECC169DFA336FC736BC995615496B9FB527C83A6192F893386C122B6C5C67E51352A7CC6CA4A7ABFC4006E6105DC7838229D44387C971375933DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D16025BE307C628551E3A1503B1D1B2C2F92108D98FD965AAF9949B00BD097F17B8B0631B752A02D85CCC07627E044EDB8C61E43DCF8A864DFE086D28C2D72CA8B428", - "084E32F1DF38B6A73FAF446541B746AA3F026119FD6D53410FBA8DCAA060AEE99E5A325ADAE77A4157E0F6372B5F34D24B05C2D6BF9589D9CFD8426C73464C350757DD655C35F577664CF2FDBDD1C8455E0271185494D6D2A42DFC62B61367B2236D6463A3A55F225BC7E66FF42A9C06BB419F7DF5F26A343792B82A81BA6F450D2D3F91272518879D283A6F4C1E4C58918CA24357FC4E38799635BAE556BD6D47082E71874C7160DD5F12E2295C39E1E148ABA3D58AD86998FFDCE98E79A0E3CDC3D7BAB4EDAD60975A494870B12E0DC53D33A33A645ADA5743E3B65F2D0F9BE54E2CAF124199584FC1A0DD9008DCB372D045FBA0D1BB1FA127E0E00F6FA03E0B8EC677371FF9B1A135696F7D79344AB7FEC2D21C2CF832B3A8708B2B80865F68A29FB86A419C135A69C3BD431961ECDF12DA631FAD16017A06BB8D1F04A9412A7CD8FA1BCE38E27ADABBCEFB99A0470694C5018E7FA4F3FA53FEF1095526B6644E999A645044F38C1DEA7BF8D9FE0E778A22486EB754FEE50CD6DD4D144E622B0D0856C008A657F4CA32A3FCB06F20A9AA75F8DFA15689B225EC64C790FBE895457E2C5707A43FAA8A5A4D5DE16B0434FBD55B6306D96FE74A5556CAA56A7AEEC92E6DE19DD83CB874D6A1AE599C0A24C5FFEE10170521E300D67EB35F5286F70D1C9D36BB72E43C81B3EFF19D2DB06B18D45C94D6B451BDFD23BA368374FB21A7371A93887F5AF30CEF230FE6A7F31B65CA27E7817195A812FED07155F0F5279F8ECBA5842292C194E03822F73CEA74BAEC375C578B5E32488AE8001E00D09F379B0E033804AD124FC0785E5091EB1679E927DEC51A6655039EA7C87657D1158DE0304881ED4F9C18AA2E8875D5A9A78BD211DFB2DF89C442B89C78BDAE7187044638DBCD6F9D99319FBE52775C4FA2CCCA0B39099E687ECBE334FA75842879C73573833510E41FB453ED8EDA633374B69B9E2717ED824F8B7DFEBBD2A5F14BF9885AB9DA241D2ACF97FD00CD3CB4D7844859579115F994AA4D1595502E646F2226E66712715D7751775220717A277FEFDEE5ECE96AD4181B953B617C4986BF839B6E79DE379425814D69885FC45B050786F7B559AC44046C8F58478CCFC2C02D7ACC699FE615226701E7F4D18567E755E0C1A3C3EEFBF51C45A6FCEE3FE0CDF24CCA87120BE2A18A50E3DEB4DB7EF35BF2BC8A5C0F5990220E73DECF7CB00E54D2D4CEAAF996E920A7F8004271B940B8F7A79C8308D9782758040EDCAA45C5337DDD2149DC8EC8B5FDD50FD77DF961C5ACCD3852983FFD42AD9C0AC2800EF86CADADA670CCCB280147E89F791E4FF092DC59016F0763AC38E23F2E4F9737812984F0B2A674C5E5AC764CC65B70BFD0E9CE2E4C3345FABA845BCBF48C8F785E04B50D3972BA5108E32B5AD3F32095C48CDDBB12E597A18732FACEA5DB9F2F980DD220F58C1AAE13A246F5C9783AEF2EF1494EB9C6FF7C197A02A4D58C418012867A62D9591F445D99E88F90FAF629A8C5FEF87BDEF2DA8D66CC588DF252EB", - "C4E4EFFE05FA703BF8D2F1BDE47FF70745EEC5A5C039FB7B41A45622F14051E4" + "83E76806808ACAAA120286650F965DEDBC6E00E13563B5547A345981FBB177A6CD6598B358F56C3B272AA2106FC8901FEC0633391BA78DD344D17A219C3AA103A8B078BB3451D690D81AB22B858231850672A92270D95209F01123E6620B043F8B64ABF9252087365E51B8789B76995EE0098CB2AAEEA6760935A9390746EAD04270B91CB08B87ED1905335895D766CB8D229AE939A154A0680C583FD2D0CD71009D8D26A9B6F90C5A463125BC63ED2165BBC12AFD5866518110C4E809CED8932F5149EEA59FE806091906CE6D53AAD7045A69A74540C738B4E948FB470073D35DC6A536475AC8A037A1DB842D742A2D2A41C708C9125EA746D309981B51719CB31A7BA412DD11AD1C1C33C7810F016498EDBA6938D00BE7902E20AC9EFAC7C8E0A22FA5EA711B0ABBA13BBE5138A11244B81AE04C65987B7A5428430980BE57575881260B1780DAF3086C94AEDD0295A793414552B2168300A5A9B077F82FB8A2B697C7CAD06078184896C0D87BD5F8A6A967266E051A2E984B335A88D59285D06775B7F25C48F431A735BC9837AF8383365D8CC06052416B826B3A888314696B7CF67F20C2345CF1113A666A1A63B878610D24744FFD9B8F8A889F3E065ECE25827E137E33E56956FC60CC2423CC6AB8F272AF00179D98E014BE1A2D6DB202399B272CC33AFB2B0F1F502636CB1CB74279D66884F0169E2FE334F268ABDCA372B36084A784B34AD0998BD742263B2119C65527F61C11816724D577B1E77A911A5D9C005F10106A7E8C6292716E27B55EDA339A7A88C62AE166FC324BCB8529C4115969E1C28237977D70C950B31C50D036B0B5584273CCF9B87250666365029F3287429C69943E488C053240B2707EF6CA58D8C840766250853A4BDB938A258B004F0705F0DA8D2D97C753884319D7A2CBBCB357DBCC1134039D205BFDA3306F61C4E28C1271112353B827A2A98996135DBD76B04D4545DDD4B111184B2A787B326A3C0466159114A9BF6C801780BAABFBB578096B73245B3EAA17161530DA777306BA614AEC5D60376288AC7F0E66A4989B93920C37F18A2F91F045DA13A2E7777FB3922A48E9211962A4E9A47BFE467B707091AF86BF8CEB111EFC9745BAA22300C447C28181721AC8A7B51C9470A8F999B7E2268ADC327C160A3F42CCA0C9094DFB65BBAA5CB0153F85225E5C83AEAC55932F19B6A9E077E2BCA1E0221EF4191DD53940063799BEE5B0A5336B6D8324A1A6AC5A865071CAC33C6930974C0A54675BE7392B8227C09EB59706442618F68FCF5977D19C06B5EC6AB8D5C3F5712B96F20ED16A1E170B40219B003A5A453E5B58AB92A786FCAFAE855D3FA66724125D069251CD04277CB1B2065728E7B4437A9954CF711616C25156353194D336F75080BD706ADFFC51D1F7163662B0F84B625226249D15CF7C33206F5249E7325548149421620852F2BECEC6BA28476935BB0F27E181E9508B9838A51DC68EBC70653ED8B5E2D68DD9895F5223A418C49951B5CCCA8494D86AB2E6D773FBB55884E2AC16DC9418100A774548E4A95AF4265772E9A3A082CED78AB81CF15DCC1C24F7D4889CC606A137B29C31A1BDAC4FB050ACB1D28D9C07B3D9973DB9A763044A6F13AF75A46DC7D480380940F9D688DE684BDF867C21EF4BDBF50908DB04", + "37782D0B89341726615D95246DA633E2BCA9D71B477B77150CACB7BB5A0ED4565644A2565EBBC4AD742AC5718F3A63518D3818A3FC31DC5552EE033522622AB75027BCC39C741B3524E51A26D12C02628BC363AA0D908330B356A412911BDB8042768FACE36B02E5126DEB6592590AC5D867EF937A2BDC3A74930C183411342AB5D0E77031859F3877A1E71B9C50200EFA04730D5A223760A62BD4B1F0615A0EA902492404523AC1F485253CC10BAB97503808C565808DEB9B3176532975638923678002E232AD68666539407AE1CEF8129702C8B58E69060DB422C49B67426214F7DB20C2FC857F52B174D6C93BE90B4A58811EE27E453382E12918652CA9F0313A8BECB7D8D7C9EC4830142539BDD92582D00234503D6FD8CE12F806A5381232D6BF0F0391EF8A1B288038FCAA98956C546AF47327009CA65326521A553F2A4E3983B052B3420D20303D378C6AF110B3451CCD5A4AE4AA83F7B2C20BC27542318690FBB2F542A3A51930E04B9FB6109C15F72B825656586C8B76F54F5382ABFE34CF91471922C9BD2D600003156C621579A0C61626A7C2D0BB7AFF95863A89C3D4722916397601630DE0E158AA9B5974A95107E0ABB6A66308123241275613C210495CAD017202508464847B4BE8792D4DC9017BD94FCE873A30C0A587A16CC7941413785AB6969CC90C47235847AD4CB1769835F195871712AA467C5DF1B30D06BB907C6519CA4AA3DC9884262339D4441C078049995BAD49FB8FD95219EA3CCF17C17F97213AD862710A60CAED990D5CF01919764218D672D9B5050AF0524A7AC67B8A38A4FA5C755050F9431584970BF6775F2609559F3807FBCA6EB67B9C67F6B0A0B4B527D563BEB415AC4989473758E31BBDC8F517911B1E431B88B7E871EA33A052FB1D2536032C561DDEB6526E652E1DF338E9C179539C891421AAF6067F550052140B89E5942E42337A1DB8CC3D88760A1498D5F407497925238A79A0B469FB2BBA70D93195F4017E0008FCC65D0635C9FDBB74EC4C4C50455E1E5B893D03764861964A9C3703FBC6A6FA557D34AA5C352D67C370DE7608E83670A48692FEB4CA17B842BCC8AAC7B0AA4546A607157DD2529182703E8AF6818E836635C428E136BDEED6678F962B1CE847D993B5F7B57370390B74261909A3963264A21DD4886A812A44CA2CB82A06EBD7C1280CA993F542EB36CB656A140471195A56C750073906B6115DC17A93E79D7E6037883349EF3B0469E984B8D63BA932BC592A09643B7C675567B676B25E46AEBC61265872CE01F61F75E4AA086B82B2F51364C3065CD880078933F606B114DACEB97AC9B535115F8166B5E9C1E23C1BD6406534A0209DC96063632682185E8E8C6B86FA3B073AA765718C8E42BBCCC16D1137270374C12A076295B0B61060341148BD64BB5553D2AE933274A034CE5CD62DE96118947877A934A28AF22F5F3410722C22B4839DC72AC2DD8222FCFB918A81ABB2422B30313484292695478F521396114A8FF0FBCCFE94A028743A7FC34EB9DBAD283C891E6A18765812FFB658EA58842BBB1232EAABDB332BA111BE36100745A842F8F3B19809C2E3C554BA3B312042C17F298FE7C1910E6774B934C283E76806808ACAAA120286650F965DEDBC6E00E13563B5547A345981FBB177A6CD6598B358F56C3B272AA2106FC8901FEC0633391BA78DD344D17A219C3AA103A8B078BB3451D690D81AB22B858231850672A92270D95209F01123E6620B043F8B64ABF9252087365E51B8789B76995EE0098CB2AAEEA6760935A9390746EAD04270B91CB08B87ED1905335895D766CB8D229AE939A154A0680C583FD2D0CD71009D8D26A9B6F90C5A463125BC63ED2165BBC12AFD5866518110C4E809CED8932F5149EEA59FE806091906CE6D53AAD7045A69A74540C738B4E948FB470073D35DC6A536475AC8A037A1DB842D742A2D2A41C708C9125EA746D309981B51719CB31A7BA412DD11AD1C1C33C7810F016498EDBA6938D00BE7902E20AC9EFAC7C8E0A22FA5EA711B0ABBA13BBE5138A11244B81AE04C65987B7A5428430980BE57575881260B1780DAF3086C94AEDD0295A793414552B2168300A5A9B077F82FB8A2B697C7CAD06078184896C0D87BD5F8A6A967266E051A2E984B335A88D59285D06775B7F25C48F431A735BC9837AF8383365D8CC06052416B826B3A888314696B7CF67F20C2345CF1113A666A1A63B878610D24744FFD9B8F8A889F3E065ECE25827E137E33E56956FC60CC2423CC6AB8F272AF00179D98E014BE1A2D6DB202399B272CC33AFB2B0F1F502636CB1CB74279D66884F0169E2FE334F268ABDCA372B36084A784B34AD0998BD742263B2119C65527F61C11816724D577B1E77A911A5D9C005F10106A7E8C6292716E27B55EDA339A7A88C62AE166FC324BCB8529C4115969E1C28237977D70C950B31C50D036B0B5584273CCF9B87250666365029F3287429C69943E488C053240B2707EF6CA58D8C840766250853A4BDB938A258B004F0705F0DA8D2D97C753884319D7A2CBBCB357DBCC1134039D205BFDA3306F61C4E28C1271112353B827A2A98996135DBD76B04D4545DDD4B111184B2A787B326A3C0466159114A9BF6C801780BAABFBB578096B73245B3EAA17161530DA777306BA614AEC5D60376288AC7F0E66A4989B93920C37F18A2F91F045DA13A2E7777FB3922A48E9211962A4E9A47BFE467B707091AF86BF8CEB111EFC9745BAA22300C447C28181721AC8A7B51C9470A8F999B7E2268ADC327C160A3F42CCA0C9094DFB65BBAA5CB0153F85225E5C83AEAC55932F19B6A9E077E2BCA1E0221EF4191DD53940063799BEE5B0A5336B6D8324A1A6AC5A865071CAC33C6930974C0A54675BE7392B8227C09EB59706442618F68FCF5977D19C06B5EC6AB8D5C3F5712B96F20ED16A1E170B40219B003A5A453E5B58AB92A786FCAFAE855D3FA66724125D069251CD04277CB1B2065728E7B4437A9954CF711616C25156353194D336F75080BD706ADFFC51D1F7163662B0F84B625226249D15CF7C33206F5249E7325548149421620852F2BECEC6BA28476935BB0F27E181E9508B9838A51DC68EBC70653ED8B5E2D68DD9895F5223A418C49951B5CCCA8494D86AB2E6D773FBB55884E2AC16DC9418100A774548E4A95AF4265772E9A3A082CED78AB81CF15DCC1C24F7D4889CC606A137B29C31A1BDAC4FB050ACB1D28D9C07B3D9973DB9A763044A6F13AF75A46DC7D480380940F9D688DE684BDF867C21EF4BDBF50908DB04620C3BA3112D18C0B347C5A0CFE56E720693645641009674E2E2F6E5DA0447A798028E8157DBAAFD5B9370227C9D876818A9A4F7D23D9567BF413F3383F8F1AB", + "F58D542A5D03DD8D622D2D61E9CC759873479DB67359DAB471DE0C6945505EF8EF61734E84EF78D5A36EEA0FE8E6006B0741C415A225834C644AFB29E4CBF207C24F7760024BA27F1BFAB5A9EC712C3A81FC2F232736BA2CA69AA2F9CA7AC17EEB89A193493800951C71812E4E2134680B3BE6FFCE9508C791EB19494D86F9192990D0745AEFED3A83B24A6E7C8C2BA6CB536D2710C49D2C3122D090B95E57C8E1DECDBAD54BF7CC1E76E79448EBAAD77284E35FA03567FC692D2D8E674D7D805899BD00C35615FAC52298BAE7D87C7CAFA3734E95FC8C7EABD0C3224BBDF0F32B61491C1C060DCDD2492516CC4419DAD6AFEF3B96A1504A9F0CE09F1774E607F3E9AC4484F41B7AF8BE402EFB12680AE98B71557562A8C1D3486C5998515D9BF87CD173F5A79BA90EEEDDFF7E0F323D8920C41A80320CCFB2157A0E9148FAFDA7FD68828E5B612B373342872F3FDB0F77F2339D96BB49D2F5E172E0523C04DE0E3C80C89F5640B84FD8B372AFB3319150D7057A9293EA36A53275FC778BE736F468AB4FDDCEF2CB40D42AB8C834B5DC08C1E3B9E7CFEA61373A46595FD2E3DCC164C7B5212F98D3AAD9FE7E08585E0111265ED71F94725E3E4D9873487C407C74B03EE254EC8D9B041D817E6E9D0827626438822595FF14503D0257F04D99352C5BB09DEC0696804260516684308C1B7B60D86A27F724D10080FA4A2B70C90090C9D3DBBB2D681EA2EDF35A73AEB3A77E4338C5631E0842AC53137379E8A653291CDE9CC3421B2417A0C59A1A3E4AF60F455FB01A65E9BCD415B77D6486495D453BA9ED0C79237313D89019FAA1BF89EF849A752389CC2A8D1E677DB68A4E4CD81A2CB9F09E0531C11BB6FCF0FAD67507A86B174F45C033B1988C6B433E9E66CA7CA69A39446FFE2B219C9A9B3CB808C067E781765991665FB40B5780E307B39C370EF01C6000660827D5CAD3E1BBD28BCE05AC0443A2806EFB93CCA9C7ED3C18FA6D58C99C5E6B6AF785636384643BD2E24F6A705012AD7A4D2E6B94CC9908C086F13515C42EFC4CDEFEB2645D106AE385D4014B983DF6A099438954586928D46476A2E70E36147B8F57DC498DC564C62CAB6C00638895D864438E8C3FB075449A7636BAD20A0C8BD433BA1C6B4E3E8E42ABD6AFD23CD6D76A4DEEBF898F699094F1E2EC5E857142C0EC0FE724F040A02CF191D2DDC0A4880D89A0ECAFF00BFD2E26588180EC93B6E3ACE0D45573CBE0B836A9547D12F00BE77B059B0F73FF36827033795F877CD347ABEE7222697440A8EE6F9F9D4747C7DF26C92CAD12747AC6442066CBEEE4B072F5E1809724B462BDD86309A08C96E23D8BDC7006129C41CD1524E9DB13475F8DBB58B9F8EE722FFEFE0628AFD711A1A66CC03F7A1D26A321093179877A1E9CB223CD688F65772C1F550C86FD9025B58F6A1DC9CEC65816EBFB2CB405526F797A500B52EA73AFE592E7A63BE79D6E2ABFE03D528154C0E8D277C844EFA398B346D96F41376FD969356114854C1997D53189404F499165", + "44CC405E3BB0A9F51A180A86213D036ED58AA0D226804E717B9C2A475DE58E75" ); yield return new ( MLKemAlgorithm.MLKem768, - "DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D1602", - "21015917953F3926871D0BB9BF7802978493FF5A24D684CDEE1B76681902FC8A9B63283C362C33FDB2385419462F4AAF9C6A9588F06A5FE52F2BC923F87123B0099D0A2B456D350B21050F14BA0EC2A56974C9A1403518330C809DF69966D55FBFB70DA27136DE5793F7E73C71ABA60A5906CD36C5653A2BECACC4459756D9E37E14E6587F40389C0895E94BC5C105C4A394098F3A5F27EBB0D4E5B338466F1C964F79322E0CC9AC17B68BD6D20FE77996A740ABF95790B69168320C320BA6602B9624CBF12C84F549E6C40CCFEABD939A934E46A8C63CB627E499D9936C8BE3927294523179224307872F9B8667B175349BA867CABC3DAC47A48A46BC001B647B7AE03878F55A7029894173039D8D1C1F9F49BE12E88743DC709F101280662EE604CB25E75215A570D3FA03A88867E8C4A84F0351AE051F90E36441366714545236CA643BD8B85FA947ECF4A536C13DD7CC6BE7485405C0CC204B91244B364E7A33A60494683A99F5E3C21BF57379061AACA63E569C0E82164633A691BE803B2CD9464996C050323C21080E8C0822730B904FFA7A656C1B568708168A4CB1F54377A02542C42694BBCC38B4CC27F7B735418346FCC8D09B52E89B8F88627BDFF73A87A07B58299AFB321B0BFB1228E53DEB899AE7582066520CC85276A0236276738B58231FC610C3C40B326C4763AFA309435B05AF1C66E84C49430B98F7D4A76A843A627693BE3A67F57C20140B94ED694A1F671C0FD378DA3CAFEED30E5C366C3509AB1E14AB1E08D029A18BE1200D1A8916A1F011B7D0A9A47860F0B09DF996939D2377BC53B7E7CBC3A9517C31A78BFA724B6DE96EE101782C0641E2EA187375B8E5579426995BAF9C30466C4160780F8900867DA89944B1AAB84BAA7F987ACF2AAD97ECA9C222BF2C34BA5F8BBBDEC2C434E43828696FC38903F4C3B7DDE727E1D36A71F9BDBC71C878A3399D346669924E1C3CC2B2AA0DB08A0F30FA703DC308E54857E4142846F9235A48538E291D683409E25CC5AD1C56B690039DF5AEEA596F52AC991E1B3D16E809BFB723A7004A0DB59F0B40885189C88D4CBAEF3ACA2951314ED90789E366EEE8AEEC84798FE931CBB3A42E847870ACC06B3885C0EB2DDE149DD802C1F32953AC20CB87899C0855B2E1D6B8B5F6929D3B9603C73BAE5C528509AC1FDB34FAB2C63773C44195010CE80A229696CE075ED4409A0D0CAA966B20D6C356C4F44272E1501B897159D544F34B7C3B0280D7FC54E223AD865307BCB36CA13729FBD36DB285CF5650C7FD451CD8B305280338C7460385464672D73C5D30A4301A611DE6751C76CFA0BC08D8958F9A170C6D0ABD75007327E891A874181BA87A9260C14378068F183EA9E1CBE1E571530856D7118D9F1AADE546691BF328E5460B114A7DE834B2B218B22BD4C83A3A4580B2C59B325B1BC68231C3732F9AB666C726BC4471E204800C27783DC8BCF6B6315FA8ACE005CCCEC92116D7B34490880452A82098B692552279609D073CB0FD58C82CA888673A093F4696F7A4CECC169DFA336FC736BC995615496B9FB527C83A6192F893386C122B6C5C67E51352A7CC6CA4A7ABFC4006E6105DC7838229D44387C971375933DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D16025BE307C628551E3A1503B1D1B2C2F92108D98FD965AAF9949B00BD097F17B8B0631B752A02D85CCC07627E044EDB8C61E43DCF8A864DFE086D28C2D72CA8B428", - "471773AF71058A5ECD58972E92A786BE8154871AE947C83025005A4F3C8D7B3F633D715FCD058431BA2CBC7E335BF25EC01A746EACC15C7538D9D1595719DFBE7E7D17305A476D816FDF3939968B97934607A592DD9EAF425A80BE250A3220763DA9BBC5E757530CAA2E188EDFFDB50DEBF6679A7C9D6650BFF7B4FBBBB7C857CD53F71C7DA5062F0329836185F5D01E8906E10C0617EA54D2109E7B13ABA51C645289EE592BAC10269B3F18868DA72839F2456FDD32B53A67C4B7BA0D67A2BF0547B0DCFEB9C626BCBEA28E90BE3A71B01F2236380F0B752A4A5E0AA680B1682F49B1B970489BAC43CFE84A2809FCDFA1BC2BA7616451C0BD65C6B5402C6D479BFF759183D0C35CC89A182BFD90B0EC368DE8B26D5995E4BC95215445701BD5F31453F578F4C5B1380E4EEA53155B9F7C73C349E8814EFBDBDB667CE7B1FDC34D02C9672A3573EBD65B1903C79C6DFEF23445DC732C4B694EC2C946A78FF7E7E3AECA89A3DA169AD7A0C9DCEAE31DAC66EC0BD66208084576C059E1F2E5F38A033A1B5C1F4B0A4F76145E29B9C47A889A47D45534640651EA4285447056FFF0167ABF1C49D16560A98DD3E2741EB246045AE365B9507B3DFEF050E43503C5A847B3BDC77E7FC87A00B4CA0519010AF0E4719965CB9F80FA3FFD2E8A149332968E81E4291F789C77B16098611E0E229227B0911757F57F4F57B9B26690191310D0714251E7460FF94D1E93B004E8716F7AF19F3F675158206662C55007039FD6F23DD54E600A39B352010CED4254D53B66A85E4B94AE985A53471F4686A483474A183F5E08A3BBDA7B1BD7708DF06800510AEB111B12ECD5C8F080D4FD165BB47F3EF6DB08175707BDE1AD3AFA560401A9F4F1484C091F5B4055F55D5394407BACAFAE553AB2F0D9A15BEFD9BE05A08614A30D55460051572D2FBFA5FD8CC0F8A9E1BA77B37570F12E4521853FA1787E6A688D5827B852FFFFEED93C01E96EC979E3288188066708339964F393B627C516BCB9460A5C9FE44F42C02432D9CD4489138F773640CD6A4D8EB188073BF95E0A40FE9BB6D49AB19BFC1BA31CAF36C2FC6535B587BC6164598B3D8E1C17BFE5D31C4D3834993DDFA54D08D1EC5F54D2A7A2FF3F11C00259D5352D94330F564177B2FB1F20F793A422F487FB6ABC7A3980241BA64BCAB5C1DE337C4A28C787B89603A581CE90788E43DBE566F1BE9CDAF70DD5C2DB269626028B5A3D6CCB1954D04E83312EB1FBF9E56F29F7A873C41021F9FE67B93274DBB03C2713C843D8B153087929E5B393971C9175FCB8D193870DAE1FDED1DF282281987C0617DE7AB275AB3782EF2EAB8F736B3F1181901AC21BFB6BEC1A071B76F622293050F4D632D0C538CC636F9E1CB6E5CBF611DADF9016DE70569CA8B31D781396F4490520A287E5BA155B388A2486BEE900397DCC033EFC09DEDF6A0581A0267176EDA21948CBC024C9B798CD2AA56A0F121E46B0D626AA2913513F7012CF17D9CF4488B193F921BB38EFFB6D67D158F16D0F616FDE", - "8EC48F32FADDB6C32DE93112DB405CE8BC525BD8FB9004999CC8AF13448D9B0B" + "DE1350105270BA1CC905F9164AF44D1F68215A0A333BA4BD03AA6A2CCBA60D0B7E74A4A41E67BDDC74A118246E4845789FD430F5BCA29CDCA9A1E47E0B4231F66A4FE9029D69337415412286BCA0B8B38BF14AADC7197B137C10B0B17E2A40CFF8430D80218F8BFA28382A026BEBAF083816335B8824A47D01647B1ABA5A8D8C2A952CCAA3042AFA9AB5216683DFC83D03419BE4662ADEB44CCBC327F038A3E2AC709372C5BF747321545319832E741223AA7AAD9827A288B5691EEA37DD785ED1222F0743C664CBB4968A3C3DD74AF0D31AD26A2BC9ECB93EEC968BB669EB76B9005B7DE9E561C0E6C75FD6074999CE1AA79A9FD8C128B853DF72740E0094E5E77F84996BCEA450B802654F555F38D11999456AEE817456C41D8ACA024A0C6D31786D738A0A387488E24485B18236243875A9241A325850A668718432B02B91A872250CF1CA7BB3D68618450DB727916961578C50AA5C8A5BE8873E8877C9A241B94B35AA6B57421C5CBD7500B180389EF7F326B27B63E9DBAA5CA8AED215782033595F79CD255BA823CB39D110AEB1307CFDA33D2B193E7D578AF73B8888B601700B1E6E742C2520C03DA05901C29993E4234552981C69CB232BA5F2E229C5231D840B1F8F667590B89A9B0C00307602932302ADB80913A35DA711A4EE5C5FCF682F6B90486FA0B728638B98606C3DDABAFAA169B3565480278F6B4B64B07AA03F0902F409772EE242E191291A06B50987CD58C16AE5983B47EA400C53B295FB8E3206ABF1B2CAA9C46C343A734027C6F221BA68B42C6BF44D806C7A728064E68BBF35F7C01383CB25EA906126623855A31A06891EA4C231300DF5933BC312430AB61F0E536E5E131EB5251C8309047F40B36F34277A31161384C90FF47ED956B0F3B66A78550FD0BAA32EA71BC4F883CD2165EEE44F81E47FB9807BE8973625148EF622B0DBC443403C0410007C99D67316A517DBE202DF804FF1133B32A9833A2116829525FB68BD2E6A7E938CB409E3878D13955B01B93D3A74A7FCAEC6A7AA6752C7B0B0B1F8C70D0A33383A3C3ACB233203628AEA70B6EA6451082B7C6EB68332324AE411B31F120A10781DB456308543771310A2F851ADAA125BE7037DBB186EB4CABDC89BADB4012364DA1FD63BA58CAA9112FA2FF5AC3642319E7A96C9CBC13C00A288DE398D55B2A06CB71187442476964D902B422B24B62674A4FFA9794009866C46978133088696A084D60A9161003B0A3F6174B7CF5836F7667AD96959F3514169183DF200CCF6F541C3AC4066129990ACACF7AC0232279B21752639566ABFA703D853741C2628C62896497B575978CFB7DA37C026B1236B0F1EEA03450736AE73AD20F8853E33B90F40CFC058BDFCFA00379A2080E0B81840993C2505D9CA5A3E59AC1377C4C176BC7EA512FEE7A1D85406A3068ECF91B0F67C79B424958421AB5E411476015C319ACFFF692D67F92753BC431B9CAF00A6B000F526D57351D6A6A63E76AA5B50212A23C64E562E8D66C7AB30843D503FBB8941E064555203ACB3C8864D0A427BF1504856688074281C66C3A7A2B0CF582E2C2293962C2022A0A26F33529E963D7C72486B24977948730CC9A89FEA714A49426669897842F4E23D9DE1575014671BA3801285563213A3FAB2D00F0D26CD453D", + "46819AFC7C032A80BB830361F0547C20CBA4B440ABDEC723C003B269B22B6ED84F159A2D691AC014E3CBBDF41F6E6B57031ABDA1C6075D786B957A95EBC65E6F6B1257637186703E5BCA5F80560613FC3192A40247B62C1D8C3A15F04D36C125B0D74EC6B087A1401A69B6A00785729C582C1194195792C164A65ECBA8077B7847DA022B1CA105D07BB68A58846DF8010CEAC960A783DC48A46BE33394402A1DB589C50A0445759632A2241AF905FFB059DC0C8D9B589A1ED30ABA265BE5D412FBCA0CAA52C662A009D21A9F00C7B4ACFB09175107084456FB92A74E903176777CBAF05A7083344823AC6A8477636C4E6AD5739189A2C1A11A21C9B4D70B6D40C37BC7B6937A24C20DA46D64877F167CBC9FF5C0B848B5225B7F24D5A76B0A66FC57A394832391D8BAE9C4CDB5930CEB66B03F52613EF40CEDD810CF2C45D0A62144227496875DC682CFAD4A4E82C42C73C6B830762D068B96B2C81BF1250F9F477B9A0A318E134D22E04AE79B4B46798C37D47E7B63B2D2F58E95841A9B673372AC619051B2BFAC4A654C07E7C714C8820724AC2994ECA3C133915215529351A66B29CD7AA9ABB31986B1677D3DE49007C3C3C3F9A1C4E52AAB1023EAE38396C301F1F57CF653C065BA7439F597D3D6BBE4395982E369DC618052B55B19453352FB603A07A24164B63FC79701A27BCD22C813D58EF86797439B0EE4CC79C9452BF1D2B71E101FA2B0BB392A661CF6B68B4BA0DA3A52C6311E706462845255AEB56C2E324CADBA74AF47CF7A0C5F23735A5185AADBCA26C1638275D045778144C6F71C5FD59B247ACC0A4B22040468DA162EE6B13005594B075C823FFBBEBF1B1EA72A866B8765C9806A374250800A50D6EA4FDF421F87286205B8C346D2348A2A2229B234B7697E18C5BFA6A968E0BA4FC6553752571D880C6C624BA3687480CDE20C018475722C8E09E33AEA03207009CF3AE62AC216A84BC3AFDDA813C7E371368016D862819AC68E5FA8AA394C3E3B94CB9A9AABABACBFA45B2F39F69CAFF354F287A0B6EC15449B82CEE7A1A9041D9D53A87953A1D45217184B2238710291777BE0C713D6F200C67B1658D8481FD88E8E33BDCFEAA88C0BBE5312516C90423DFA92E8AA927330A4A10B884685163CB0A9084990D832C6AFA960223A14D8085D07EB29587CC23B50A5897B969C471703DAC3C2D662FD1C8CA568674D230CC994857AD5C6180B10D3510CBD018966654E314C6CFCC979D0B428EF682DE27081E0663BB1A5B8A11AA9D7495BA2674CCE8698705142B7627CD34ABD81FA96C43829AAE87FDAD3C2518B8189EB8ADD0B24C4302B66F9C8514361947086C0E26263E659EF446AAC4179F4AC4AE08BCD710C63B1B18AFF405E2B793BCB8A6DFB95ADBE52AB0009106B0596AB72BB50B7AFF25A1822C693876CC54292ACE2B25C501836414C08324508861A06AB40778412A65F6699E548916E9CA3A8AB4D68394799653A99785D11DAB151E4A433C1C6D6CB7973168AB4A027DD0639381306BEB52420F7000D81AA1E0172128B5018B0402021B49CC708FD5A00CFA95503DA95F985A4CBE60FBEE8C96440743ED49CF8DBB017815EF17561E56B04D7E03B870726DE1350105270BA1CC905F9164AF44D1F68215A0A333BA4BD03AA6A2CCBA60D0B7E74A4A41E67BDDC74A118246E4845789FD430F5BCA29CDCA9A1E47E0B4231F66A4FE9029D69337415412286BCA0B8B38BF14AADC7197B137C10B0B17E2A40CFF8430D80218F8BFA28382A026BEBAF083816335B8824A47D01647B1ABA5A8D8C2A952CCAA3042AFA9AB5216683DFC83D03419BE4662ADEB44CCBC327F038A3E2AC709372C5BF747321545319832E741223AA7AAD9827A288B5691EEA37DD785ED1222F0743C664CBB4968A3C3DD74AF0D31AD26A2BC9ECB93EEC968BB669EB76B9005B7DE9E561C0E6C75FD6074999CE1AA79A9FD8C128B853DF72740E0094E5E77F84996BCEA450B802654F555F38D11999456AEE817456C41D8ACA024A0C6D31786D738A0A387488E24485B18236243875A9241A325850A668718432B02B91A872250CF1CA7BB3D68618450DB727916961578C50AA5C8A5BE8873E8877C9A241B94B35AA6B57421C5CBD7500B180389EF7F326B27B63E9DBAA5CA8AED215782033595F79CD255BA823CB39D110AEB1307CFDA33D2B193E7D578AF73B8888B601700B1E6E742C2520C03DA05901C29993E4234552981C69CB232BA5F2E229C5231D840B1F8F667590B89A9B0C00307602932302ADB80913A35DA711A4EE5C5FCF682F6B90486FA0B728638B98606C3DDABAFAA169B3565480278F6B4B64B07AA03F0902F409772EE242E191291A06B50987CD58C16AE5983B47EA400C53B295FB8E3206ABF1B2CAA9C46C343A734027C6F221BA68B42C6BF44D806C7A728064E68BBF35F7C01383CB25EA906126623855A31A06891EA4C231300DF5933BC312430AB61F0E536E5E131EB5251C8309047F40B36F34277A31161384C90FF47ED956B0F3B66A78550FD0BAA32EA71BC4F883CD2165EEE44F81E47FB9807BE8973625148EF622B0DBC443403C0410007C99D67316A517DBE202DF804FF1133B32A9833A2116829525FB68BD2E6A7E938CB409E3878D13955B01B93D3A74A7FCAEC6A7AA6752C7B0B0B1F8C70D0A33383A3C3ACB233203628AEA70B6EA6451082B7C6EB68332324AE411B31F120A10781DB456308543771310A2F851ADAA125BE7037DBB186EB4CABDC89BADB4012364DA1FD63BA58CAA9112FA2FF5AC3642319E7A96C9CBC13C00A288DE398D55B2A06CB71187442476964D902B422B24B62674A4FFA9794009866C46978133088696A084D60A9161003B0A3F6174B7CF5836F7667AD96959F3514169183DF200CCF6F541C3AC4066129990ACACF7AC0232279B21752639566ABFA703D853741C2628C62896497B575978CFB7DA37C026B1236B0F1EEA03450736AE73AD20F8853E33B90F40CFC058BDFCFA00379A2080E0B81840993C2505D9CA5A3E59AC1377C4C176BC7EA512FEE7A1D85406A3068ECF91B0F67C79B424958421AB5E411476015C319ACFFF692D67F92753BC431B9CAF00A6B000F526D57351D6A6A63E76AA5B50212A23C64E562E8D66C7AB30843D503FBB8941E064555203ACB3C8864D0A427BF1504856688074281C66C3A7A2B0CF582E2C2293962C2022A0A26F33529E963D7C72486B24977948730CC9A89FEA714A49426669897842F4E23D9DE1575014671BA3801285563213A3FAB2D00F0D26CD453DF0557B4190F81298E44F5A57B35DA4E38A8D970A89E0820A5AE30E7F77CE282425CA39F4A6918F5B97B9580AA6019CDFC5604A13B2EE4D72F5D0896F0C335D20", + "49C77EB019FA3D007EC426C759E07A7740E5C63AE8D0DEB905BEABF4531BCE762A7A455D45F571218C23A434054DCE1D7C65D3557C3D4301688D72D95A14E052EBBE6AF4C2D878837240BB8473D4023B5B0E74DA7AE7B6ABBAE062142B8B06C195623B88757564D6C58C0F929A96E43DA3450B08E0DA716FE52CDD51CA5883548B61235289A2E0F657B250233EF8639DA08E6E10E4A6E75291851F729F89DC37601C520D5A1904CA9D752EB655F9A73190E7350AB410348512BF9CE650943FE41C03BED22DF45CE1B09585E20C67DF556B05D68BF64251508FE8012EB845720E2AAF158F1B069374FF3FE7293A0DEB05CF914EC5C2311ECD4657A4BF55B7DC94530703A60EEC3BFAF70CC0CC1A2CC1C147E35AF6073716F4BE540DB1FE13BEA22B7175BB50D7C15F044AA54B126C69E57C1D4C5C5A9CA947AED4FD279DCB950D6408B62E7940AE12076702E553E604340768A870931FF3CC5C0F4C158F1322BA6FB6E3ED4B5421ED5A2F5949004E885E08E7F87E631C8674EC7310240C16F24B2B5A9175DB724628F1F0CF76088ED5EDDA985635C614BB0DDBD79D3CCBDE0CAD1CEB9A3FB536F71FB5DD0979FB87F0A8D4E33EA11AB19A98F36AEE54BF7870CC22DD4D4A2C375CFE9A68FE64776E612999BCD54334B601934459D0FC18F78259FC4E5A03E6A4996BC66EC0489C1C012B43195DD2EBC6C9A45CFCF2E3AB611E987A9BD527FD89FFBCAF78A2A8E03F1FF07378722C9E624A066F161466D4405E851E70752B7A963195DFB8CC8DD4510FA699CD0B0BC0213EC6662CDC9273A8F2648D4F68CE6EAAD00934CEFBBF8072D0814634444534ADB4CCFB36E5067594E5723893DE05F7312B380DC08486563A0496AFF6F2349BED9E44E09399E1F769440740A7E52097B616E58A859A5D3C7168364CB0C746B524EABE1E51BE8D4CFDAF80A73B8C6779B70B899086D12AE3662D0BC196151F7724194B2E01295E08FCF3C9FAB46CBAE3F96B3BBD6A66D51AEEAD6C4FC2875C5C2227F12E227633264B8C658D867AD67A85EBF8B9732FBBEB08103C733E7ABFE7F6928F414C9F780F2C9F80BFD27E212EB007DA10322034021301497D5F7911C11F64889685B6B6A7C51562CE13C6E8908B6F62246FE6A2A485C0B1BB0038BDF3FAA4CD22FA450E375B0449802D8D96DD33A6A5EBB58EE78A25AA33E8F737C5346FE135324146830259E927BD1E72FD208F2C906792C60DF161448EDF57E6BF77D6B9DAC24A17694C996E92894B9F350799BBDD7E86F30818960BA56FD23B07DB2605392C0A9E152E255CB4FF6FFE3B5BB5153E0AAE288C97FCC0479F3867FC5247E850A9F9406AEFCB87EB282FC46427AC4332D69940153B1B8607E9EA3F5681C9EF1E9E0CD06457187A72C2A10C61C7F39786C7608AFB0D19857A1EBBD333D148FF23BF54AD18CD21019C134BD5960A964ABCFD4364ACEBC64F09243E25A9B5E33A2AE51BB0523D59901AE4FD946DD0977F6FF46CCA2FE7003CC3AE90FB85A3708F0C0DF6A2E5FCA2BD46", + "0E2D4CD0C4C4C9520E5F35D12BB21A087DFBDD502BAF4CD898A31C4F16B6CA67" ); yield return new ( MLKemAlgorithm.MLKem768, - "DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D1602", - "21015917953F3926871D0BB9BF7802978493FF5A24D684CDEE1B76681902FC8A9B63283C362C33FDB2385419462F4AAF9C6A9588F06A5FE52F2BC923F87123B0099D0A2B456D350B21050F14BA0EC2A56974C9A1403518330C809DF69966D55FBFB70DA27136DE5793F7E73C71ABA60A5906CD36C5653A2BECACC4459756D9E37E14E6587F40389C0895E94BC5C105C4A394098F3A5F27EBB0D4E5B338466F1C964F79322E0CC9AC17B68BD6D20FE77996A740ABF95790B69168320C320BA6602B9624CBF12C84F549E6C40CCFEABD939A934E46A8C63CB627E499D9936C8BE3927294523179224307872F9B8667B175349BA867CABC3DAC47A48A46BC001B647B7AE03878F55A7029894173039D8D1C1F9F49BE12E88743DC709F101280662EE604CB25E75215A570D3FA03A88867E8C4A84F0351AE051F90E36441366714545236CA643BD8B85FA947ECF4A536C13DD7CC6BE7485405C0CC204B91244B364E7A33A60494683A99F5E3C21BF57379061AACA63E569C0E82164633A691BE803B2CD9464996C050323C21080E8C0822730B904FFA7A656C1B568708168A4CB1F54377A02542C42694BBCC38B4CC27F7B735418346FCC8D09B52E89B8F88627BDFF73A87A07B58299AFB321B0BFB1228E53DEB899AE7582066520CC85276A0236276738B58231FC610C3C40B326C4763AFA309435B05AF1C66E84C49430B98F7D4A76A843A627693BE3A67F57C20140B94ED694A1F671C0FD378DA3CAFEED30E5C366C3509AB1E14AB1E08D029A18BE1200D1A8916A1F011B7D0A9A47860F0B09DF996939D2377BC53B7E7CBC3A9517C31A78BFA724B6DE96EE101782C0641E2EA187375B8E5579426995BAF9C30466C4160780F8900867DA89944B1AAB84BAA7F987ACF2AAD97ECA9C222BF2C34BA5F8BBBDEC2C434E43828696FC38903F4C3B7DDE727E1D36A71F9BDBC71C878A3399D346669924E1C3CC2B2AA0DB08A0F30FA703DC308E54857E4142846F9235A48538E291D683409E25CC5AD1C56B690039DF5AEEA596F52AC991E1B3D16E809BFB723A7004A0DB59F0B40885189C88D4CBAEF3ACA2951314ED90789E366EEE8AEEC84798FE931CBB3A42E847870ACC06B3885C0EB2DDE149DD802C1F32953AC20CB87899C0855B2E1D6B8B5F6929D3B9603C73BAE5C528509AC1FDB34FAB2C63773C44195010CE80A229696CE075ED4409A0D0CAA966B20D6C356C4F44272E1501B897159D544F34B7C3B0280D7FC54E223AD865307BCB36CA13729FBD36DB285CF5650C7FD451CD8B305280338C7460385464672D73C5D30A4301A611DE6751C76CFA0BC08D8958F9A170C6D0ABD75007327E891A874181BA87A9260C14378068F183EA9E1CBE1E571530856D7118D9F1AADE546691BF328E5460B114A7DE834B2B218B22BD4C83A3A4580B2C59B325B1BC68231C3732F9AB666C726BC4471E204800C27783DC8BCF6B6315FA8ACE005CCCEC92116D7B34490880452A82098B692552279609D073CB0FD58C82CA888673A093F4696F7A4CECC169DFA336FC736BC995615496B9FB527C83A6192F893386C122B6C5C67E51352A7CC6CA4A7ABFC4006E6105DC7838229D44387C971375933DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D16025BE307C628551E3A1503B1D1B2C2F92108D98FD965AAF9949B00BD097F17B8B0631B752A02D85CCC07627E044EDB8C61E43DCF8A864DFE086D28C2D72CA8B428", - "7D092F092F100B95CD9E18B6DC23C39A8B7EED57229EEE522368CE83A23C766FC3302CFFEC6BF67C558BA2F5F20F277879B8D676C75CAB877A060BB4DBCA827F4E35D54BBF0067FB0DCC82702610CFB7DCC90307D733CF59CDA8A84981BD24DD3E146D17C3ECF2DADC2CC973CE3AE1D2881D143A1A55B60D0574291F7E1D77C9D8EA09F71C7F9285DDF072850386B0718D14E788582A92815661EDC2441C57529F63B9F0EF9846C1ED907FA1712B37D9814C70DFB5CB63B385586C1C4B7E91A900BBF532041EFA0EA49358136E916DCA2FCCE4E17BE8A2FF3295BAEBE474C5257069102A50CA9801597E5EFE64DB41A7A82E22B1291F83945FED077F4360F56329CDF2063C3939AA1B284C6BAB65A1DDF20BD97E17B41D03098544B56242FDA328FCD7F69DD372A05B8FDA48F8E5CE27F1B2A917344078000E5CFA5C498FDDB77256827226D63576B51B6BC8ADF81C6FDE9343D469FC866968A37AE506287945AD358FD3E8A3A37FC7FC86DBA5D29CA91F7C80E62D1341B23539A96B38DAE2FC4B615BCE7A3C44448D7ECF7E77B60DC2FAD8BAB64FA3EEDD9F1F5A92F9AF7832305705EAC6BFA9E83D0D2BF162A567E82E59E763775983B5ACB6669AEAF70E756365C14951B963410CAD7944A9AD8D8229D18F0871D8BAEE7C241DC69C0B525B08817593FD136555837AD2F580ACA465F75D1832681652E0ABF66976096AC9A72509A9C34CA839AF15FC33F25B7234EFE562B5EB7597D116499C56CD931EE99611619029A6D5EED99A03C7A45E1FAA6F82BDEC813BB39183AB62721F7FC1BEDAE5BE2F1D1CB22806C9992C1DED298515A63A9C8DEAC6B094F56C363FECA93C2D051E85AC1DB7A153A511A7B3EAF0EC7D29F8B593C2A77BC93E649BEFC306A4AA766099F4FC9FA30882E9790D0F3A77001989CCF41C58EA1562FBAEA842E20502650848F2670D0B9706122678FC910865BEAB5977649D6B04438AA77FA49D434C30F4946E53DF2AD529682C68E20DC0CB0BEE2FA1CC507F73E42645B40971E211C6AE319955168EF22D85FB7EFD9E75408121B0BEA27B537DC088F044C2B7831122B494A356EED1B306C8A114D668EFBDE1F75DCD07AC7AC832449B6F15B0ED9B9CC70482019AC8A3799C1A5EF0CBC1A3CF0B10DBAF16A61795EE27E35C0202AE18CFCDF0BA102D6E40DA93CCDF09C529ACE87C09EBA80D63D8167F3EF89020ED6D1EAC29FBF40912E8D3595B57059653445BCE7B8AF49B575AD4C14D9CF2218865B6FCCE13533C06B15E94B6B8FD1341CD56776E17AB9B2742BBDDA91450527336C596711B236F52DC63357C47602570495BF208D3D9906AEDD466A0C0518910D0954F375173452C2D4DEC28B139D04B7376EE694669CA675771C7F351079ACEB1C71A5FAE69B99C00F4AD93C9CE08A291FC6DA670534624747D8AFBBDA6875EB20A4C03529C67F7B3D0172359E826C38B3C7067DE1B2E7FCBD4A7BEFA3D6BC3B4B44E1833428E81CBEF09BCF2E359DD4DDFC5A353AA779DB26537BF5B5B351E", - "498DA668615D45F52F47EF960E634A7BAF74B0A6EE8D73DECAB67E5C096C4FB0" + "D9E7BA6E19437BCCC947EBC3DE0B9B87E2029E58C4AA2BB7750B780C20C5330CCF83F01760D561976ABACE156F1448C3971679DB529E280AC4E17B67A5F54B7E5072ACD4BD1F4B2C4CC133E6480569AC86FBE368D102CC26338ACD8992DC60B80AF834DDF1B615A23B97453C5E8A5C705B5CF191B79CD32F30711BB07C341CF7C93FC055B4850581167F7A180BD448C0F15858D00353B3903C984169A524AC74640F7169C3C691C0E9FB362CCCB6283C9403613BF545C20DB6C21AD96615422A79FA4810F59691F16ABBB0AC18C035CB2233A80AA7CB050F44283F01279F9DBA4AC2D712A0739DA5B5675776C2BAE37C6D4C17A57230A3356DD691B87278CB85673DCF0C135CD6CA40697215396A67B03345B5AF5371B74E101D8D284221F08E39770A86130CF10B327411BCAC3CB20F234F260AAD1A1220873BBDA9658B98237EDA14065A48C77FC2351E8AB0995CC428C581D400141C1B6F31555C42FB649F893C93570C8BC00585AA21327666AA5C861BA01FB91A60625B8167C663D6B8CCB93851C7236C88D8353A25026C87ACD2A16374F213D37B10A9143C7CCA4C73F881926C89BC31C62AC2B643856877603DD24C032B6A90CF661023FB44419897E22168553A4FB046A2E5BA788951CEE12C3D501556CA8744FD47245446916D88065A522C9158A82BF1B495A91504ABCDE6774F51B405D994332B5735D925875AC7BDE26927FC9092811CAF614372B357B88B3C23BBBC44E880B98D7981EEE36F255A4683E86ED3A03434E1C075B3348429804095A647D53400D480FDA3381DE897EEC08243E8A2CB2C174BF79EB4EA3C76C42DE8DA9ED1E3730BBB655942A452404A0E046DA8B06F29FB51B69058D8B2413C79C3DD8C8EF7538F35E8C007AA5867B8076602715FA98FD7B89CCA9764DB94CDB657413445BD93E095D70B2E0E397788020A0F38B466772739211436727316447FE7469D90D21E2697C5D9614AA6927EE68B368573B1DD2B26AA0B9706598D863B3AA5D74858D5445A59B3829877E26178511115925B65BD367203B8592CE34ACF2A67CF80777FF5A8E88B7E2DD27383F8C6657A012704BD556374313C3D4F257F1D104E2B5B631F41C5D8992344D8C9408B8F63A5C5E479B432DC5C1295C0759406482689F62C47F30B291E3AA5A04AB762663B5DB360C7481FE29002CFB16616F50C1F1CB93BB8828DB22A02E2BD2E166433398436CB92161974A64C73D56857CAE5BF7EA07B5AE9C94DCBCAFDA81AF4BB6BB23A881E181BB6902B9360BBC4B4730A6CAF51B78190916E50503E572951555585156762C547B17D19B4E5D8C43AA63CB331A7E44B2151B0B31F61A1C7628648D0381A7A9C4FDB2B9E2998CB7121ACF280FEC30AD657619594A9A6A8106158A4379B3FC845A2F369267E41C84D8309FBEA7BFE9201B6F25125326FA10A198818ADD1AAB6010A7DC220A19C490CC5CC2478970F183C2FEBD346B35CC6A3A399B29BBC99E7C661D27EA6612068609CFD91B890A9C092AAA638C923B182001D54C87D09A45E5B58FD11BD3965B621F426F9C09A79A39775D4144A64CF0142C8585120552692DD503FA99C206F7203FBD765E5E094F4666891310CAC0CB6D8DA16DE0D7B4079BB462963D3BB50DBD799825A89FC965130C429FC78DEC0BE", + "5CB4C2E47C20D4D968A9E55D1A4A1CA172A154973C60F1BD55FC3A6DC8184A17153AD0059E0824EA12238C3068D6553636F19DCA495EE2064762292BC318B144667CD9438A2C32904DF01AE90A11FB0828F0DCC150A02F7E758BB95C3B64F093ABDC9D576915103954E67B7AB5D271F1603248B16B15C8B913202E85461A4E9CC589C54A0D3041C2B6953E73C24C5C6F0B9B6BAAF63CA11863A2E47420D790AED7CFC83C6BF5C15AB4DAC00F9239B7848231652473322282CA0F34F73C6D9C25040CB2076085D85186349B03A518CC720C0AFFD37E61B56B394CAA20074AC86195E7816AB037AB3D300B9FFB6892199122E703FAA7C6B9C34D8445593BDC00FC786C7CC206898325E44338E74B02AE931D95AC50DFD42FE6C16EA7A344A4304FAD54838AA9B78101B7E803A33ED6822E7C8FDD693A5B3C9F45ABB3893C6680C765149266C16105735A9F94B4B6E0A78A94B537D37A7EEC131AE32545BE14BF6C42384C9B9C7577001492254B7A85A6955551E52011656D95B236B3C10B7CC79119E5223562C3BE2A5DBB527110BA54B852C99F7607AEF66AC730003EA0A170836B22289FCD39A2F5478FEEF38799A28114F3875A7A226FF7A2295858ECA953F7262A6A886087FAB084B7BCEC4663486077B7E7A204EB4A9A7374CE07D09E61C5CD6B168BE584F19C513C35A2951033445251CF6BC85DF872B8DA47F0B00C17391F66706D2BC65B698AC85B36ADBF166FA6A23764562C69FA57A5F2B6EB836883796DD671A95AE4B44A47BE78B22E775C233144A0D95B6C8393AD16F39E217C9FC59C77866B12E0039C480945D98B6A25FB9F0D4ACE6F102039171932F27B7DB10CF0239707D45A2BC84C4A0005821A3B430B125D02934E360193414AD85151E1F4A718A64CEAD112AB5A4206CCAF71B9AD91EB5B2068C1AD04CAAA3238E77355CE71228D962EB4E4AE7B499019C1CA15179027103EF85AB16B0BBC538A955100C328845BFE5199680861F6C865046928264012A7529C6B55B79BE27CF497308408A1A821658D8AB146146F32770B5B173E2B45B97BCAA0B833B68C5981646B3A9C2630D98B4193F6231CE3C68EE1C3F8B5C4EDAC4063D7585A127C22866E96B6984B71132CC90F3844046CC7C23A498B65E4349E9737363946BE782BA811CC67B82380DB87C5F71FED9587D2E4C37EF211ADBB39C973B07266841BF2A0E4F8CF40E62B9FB647232A111DC56028A73B43143E7D671AC1B964EB488EF932510E231B08A64DD83C3A3FE1C2C1A2644AEA554EE85264F4768226382BC5502605519B91566E9C7D52D1922D87BDF1E3640545C70B9C61D402670298119EC26569632A71A362CD151092F21892BCC179252391F0122EEA25CE20590E5605583C28A6F30E26987C23D56FEFD49D8DDBB0C27684713C4BCDF4411F66B541996DAB7025C3AC1E0E424D112A9D27A58CA78B6FAA00616794492808B5E2B48A05240ABC3A6F7EF5339E7A530F703554024D89F0C13514668CF8864947BBF3721325415C7BE738C321482DEA3478D019D2F298AA7B315A468DC13CC39CC0B67FB29C72611051269B42279AA25B942C6152209CA168026288F77515E9BB054CC1B5A3435D5771D9E7BA6E19437BCCC947EBC3DE0B9B87E2029E58C4AA2BB7750B780C20C5330CCF83F01760D561976ABACE156F1448C3971679DB529E280AC4E17B67A5F54B7E5072ACD4BD1F4B2C4CC133E6480569AC86FBE368D102CC26338ACD8992DC60B80AF834DDF1B615A23B97453C5E8A5C705B5CF191B79CD32F30711BB07C341CF7C93FC055B4850581167F7A180BD448C0F15858D00353B3903C984169A524AC74640F7169C3C691C0E9FB362CCCB6283C9403613BF545C20DB6C21AD96615422A79FA4810F59691F16ABBB0AC18C035CB2233A80AA7CB050F44283F01279F9DBA4AC2D712A0739DA5B5675776C2BAE37C6D4C17A57230A3356DD691B87278CB85673DCF0C135CD6CA40697215396A67B03345B5AF5371B74E101D8D284221F08E39770A86130CF10B327411BCAC3CB20F234F260AAD1A1220873BBDA9658B98237EDA14065A48C77FC2351E8AB0995CC428C581D400141C1B6F31555C42FB649F893C93570C8BC00585AA21327666AA5C861BA01FB91A60625B8167C663D6B8CCB93851C7236C88D8353A25026C87ACD2A16374F213D37B10A9143C7CCA4C73F881926C89BC31C62AC2B643856877603DD24C032B6A90CF661023FB44419897E22168553A4FB046A2E5BA788951CEE12C3D501556CA8744FD47245446916D88065A522C9158A82BF1B495A91504ABCDE6774F51B405D994332B5735D925875AC7BDE26927FC9092811CAF614372B357B88B3C23BBBC44E880B98D7981EEE36F255A4683E86ED3A03434E1C075B3348429804095A647D53400D480FDA3381DE897EEC08243E8A2CB2C174BF79EB4EA3C76C42DE8DA9ED1E3730BBB655942A452404A0E046DA8B06F29FB51B69058D8B2413C79C3DD8C8EF7538F35E8C007AA5867B8076602715FA98FD7B89CCA9764DB94CDB657413445BD93E095D70B2E0E397788020A0F38B466772739211436727316447FE7469D90D21E2697C5D9614AA6927EE68B368573B1DD2B26AA0B9706598D863B3AA5D74858D5445A59B3829877E26178511115925B65BD367203B8592CE34ACF2A67CF80777FF5A8E88B7E2DD27383F8C6657A012704BD556374313C3D4F257F1D104E2B5B631F41C5D8992344D8C9408B8F63A5C5E479B432DC5C1295C0759406482689F62C47F30B291E3AA5A04AB762663B5DB360C7481FE29002CFB16616F50C1F1CB93BB8828DB22A02E2BD2E166433398436CB92161974A64C73D56857CAE5BF7EA07B5AE9C94DCBCAFDA81AF4BB6BB23A881E181BB6902B9360BBC4B4730A6CAF51B78190916E50503E572951555585156762C547B17D19B4E5D8C43AA63CB331A7E44B2151B0B31F61A1C7628648D0381A7A9C4FDB2B9E2998CB7121ACF280FEC30AD657619594A9A6A8106158A4379B3FC845A2F369267E41C84D8309FBEA7BFE9201B6F25125326FA10A198818ADD1AAB6010A7DC220A19C490CC5CC2478970F183C2FEBD346B35CC6A3A399B29BBC99E7C661D27EA6612068609CFD91B890A9C092AAA638C923B182001D54C87D09A45E5B58FD11BD3965B621F426F9C09A79A39775D4144A64CF0142C8585120552692DD503FA99C206F7203FBD765E5E094F4666891310CAC0CB6D8DA16DE0D7B4079BB462963D3BB50DBD799825A89FC965130C429FC78DEC0BE8791A5FC5C3256093B6A2771B74BAA0E7A392BE9786539C7D779967E1C808359E68078657C842E8DAB13CBDF6F7F8ADD047FD559D7301C13F6012418DA0E0889", + "F4992501CF2F2EAEE6D1417D8D17317D61A33D8C3BD6E8E85ABA5EA7847077B3675F64C9EB4BE036BEE72C51E124FE95594B9740401FB09025D3D2BD5E277D562516F2AE98F0DD8301C3E069A81E395B8906B5EE054F0929C6C1127B36186CD121B960C582CEF4BCA24FD70D55A33851BECEDB0BE236608B4AEB1A28DED9730B28F3B3DA55337F12B88CCD7073C14E4D8133BB949F656A916A5BD661FFD7320818316DC695DD7D26F8CDA18C7F75224D635ACE8E276F747E73D78D42ECBFBCF8D54D5B5483F8574121C422E94A72E9BAC36D5C2FDDCAF8F5AEE6FFBD4D29C11E2FD2F26E93CBED40573F0D3AF8AC3CA56F8226D4FC5A17818C1087449B74248C2C9AD52CC279CAB0D24CC7EFC60499F927F7A8898C93E42C0859F9E76EDEE539F737BC047E5DBBC9E0A948ECEC3D6C998CD2F870C7858ADFC495C83C65CB069DF557E26E6B0FA3F2182B33E93FE2ABE2CA6F55B3022A518B7E8885BF7357D99C5A8C49D13D9D31E3B845F4641C8C18F4AD79C25E2F854566DB4EA208CB0AF3302793AF0CA778491C666C0664EA0FF3CC79EA6FF2F4DDA3A5228ABF635E8002FEC9EB376B7F709E73A9A162ABA9E14898C3DDD999F5D3EC14B24CE733A30B0529FA6B827482D32031832A907F2889251B9A54B705A19097F7D83F0EF180251BD2A4398DD500820863D051C2F6DFC14D4E712939DCF93D2A79DD985B22025112CDBCBF2F293149E343993546FC8B5DC9CFB7244C9CDFAE8134FE71F1EB60DACFEAA63A61E80EC02B94ACD3BDAA73051ABCC54D09486E6FD3ED327A947926CBC26B185F7F0620EDB773DC5AEA75711B94A076E306CEEE1DA7AEEC03C713D193281F62107877EB6C2238FC4230D263F30CCD17BF3D23138055874B3ED4415203A9AE367F9AE5B235B5A28957EE12D8F256AC6F7B1F7168C6281EE9AABABAEFF5EDF24F9E4F11598ADDDF15E62BC1A706A19CF6E827F049A7B62F185D2D02D92359A76D53C7685230934BCCF1D99F49966BBCBF57539531749E79A3B194BC0AA6A4A139BD5C622F65158B2C1EB18887F998A9366277736CE47F7BA7A255F6B4953E32E8E70A18D1D18914D495CC93887D523BA1D4830A6C71CB2533238819511D4E4AC6BCF736557659908D49AA58A29A5E66E4A10139F1A883CDADDA4F2B874F89DAC2E9B8110347E62DE75C6B5D9D64EE1150554D3AC40EB0EF49BE3D21C3FE2C3C6ABA7BE55503F933864B8D0C68C38AE6E0AC92FBE31EB2A8F5AE3F031B1A201473B3ED05FB291E97386ECF56CCAB597FA4CD43B09E6DAECE3B24840A459BC6045543F140E52B98AEDF21DC5F14074F2EB673800604A588DC0F0D13A48246FF3BD31D3EB9C6F110391927322FC8F4C9602935430D94CC9033BF1881C1EF805377C7D10C55A5AF2520A0A9D459EC13E4C59CB80CCF0A64B092851DDC7D418ADD1C8BF91E45623411B4390CB870F63DBB9A014E98FF19D5C8F54B64EBF931A4124D8133D7A9CB5A7DCFF89313F39A13075C70E68CA8D82F9E9A0E4EAC76ABD148DA", + "DF79AEEB00A7005010721C0E9343ED2EC1B837DE5561D1E68CCDE437995BAF38" ); yield return new ( MLKemAlgorithm.MLKem768, - "DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D1602", - "21015917953F3926871D0BB9BF7802978493FF5A24D684CDEE1B76681902FC8A9B63283C362C33FDB2385419462F4AAF9C6A9588F06A5FE52F2BC923F87123B0099D0A2B456D350B21050F14BA0EC2A56974C9A1403518330C809DF69966D55FBFB70DA27136DE5793F7E73C71ABA60A5906CD36C5653A2BECACC4459756D9E37E14E6587F40389C0895E94BC5C105C4A394098F3A5F27EBB0D4E5B338466F1C964F79322E0CC9AC17B68BD6D20FE77996A740ABF95790B69168320C320BA6602B9624CBF12C84F549E6C40CCFEABD939A934E46A8C63CB627E499D9936C8BE3927294523179224307872F9B8667B175349BA867CABC3DAC47A48A46BC001B647B7AE03878F55A7029894173039D8D1C1F9F49BE12E88743DC709F101280662EE604CB25E75215A570D3FA03A88867E8C4A84F0351AE051F90E36441366714545236CA643BD8B85FA947ECF4A536C13DD7CC6BE7485405C0CC204B91244B364E7A33A60494683A99F5E3C21BF57379061AACA63E569C0E82164633A691BE803B2CD9464996C050323C21080E8C0822730B904FFA7A656C1B568708168A4CB1F54377A02542C42694BBCC38B4CC27F7B735418346FCC8D09B52E89B8F88627BDFF73A87A07B58299AFB321B0BFB1228E53DEB899AE7582066520CC85276A0236276738B58231FC610C3C40B326C4763AFA309435B05AF1C66E84C49430B98F7D4A76A843A627693BE3A67F57C20140B94ED694A1F671C0FD378DA3CAFEED30E5C366C3509AB1E14AB1E08D029A18BE1200D1A8916A1F011B7D0A9A47860F0B09DF996939D2377BC53B7E7CBC3A9517C31A78BFA724B6DE96EE101782C0641E2EA187375B8E5579426995BAF9C30466C4160780F8900867DA89944B1AAB84BAA7F987ACF2AAD97ECA9C222BF2C34BA5F8BBBDEC2C434E43828696FC38903F4C3B7DDE727E1D36A71F9BDBC71C878A3399D346669924E1C3CC2B2AA0DB08A0F30FA703DC308E54857E4142846F9235A48538E291D683409E25CC5AD1C56B690039DF5AEEA596F52AC991E1B3D16E809BFB723A7004A0DB59F0B40885189C88D4CBAEF3ACA2951314ED90789E366EEE8AEEC84798FE931CBB3A42E847870ACC06B3885C0EB2DDE149DD802C1F32953AC20CB87899C0855B2E1D6B8B5F6929D3B9603C73BAE5C528509AC1FDB34FAB2C63773C44195010CE80A229696CE075ED4409A0D0CAA966B20D6C356C4F44272E1501B897159D544F34B7C3B0280D7FC54E223AD865307BCB36CA13729FBD36DB285CF5650C7FD451CD8B305280338C7460385464672D73C5D30A4301A611DE6751C76CFA0BC08D8958F9A170C6D0ABD75007327E891A874181BA87A9260C14378068F183EA9E1CBE1E571530856D7118D9F1AADE546691BF328E5460B114A7DE834B2B218B22BD4C83A3A4580B2C59B325B1BC68231C3732F9AB666C726BC4471E204800C27783DC8BCF6B6315FA8ACE005CCCEC92116D7B34490880452A82098B692552279609D073CB0FD58C82CA888673A093F4696F7A4CECC169DFA336FC736BC995615496B9FB527C83A6192F893386C122B6C5C67E51352A7CC6CA4A7ABFC4006E6105DC7838229D44387C971375933DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D16025BE307C628551E3A1503B1D1B2C2F92108D98FD965AAF9949B00BD097F17B8B0631B752A02D85CCC07627E044EDB8C61E43DCF8A864DFE086D28C2D72CA8B428", - "69FF299E2D6B9D9644BC6A51D99B4C7090B5D1B57D07940FA9FDA30700EFF7DB60D970D56F65667D5F9B40224E00D0499030EB3A3419043D366534BB688F9ABAB691D4B6042B992FE700B8D9CD692BE1D866B6109330190F1BB62BCA02B3C4AF50291142A05C47E94833F10E3E603C7D4E609117944924C4DA9E25E7DE5923B29CEFD0D2D369D7BEF447B63E7E4A332AE9041571DD91B20C459E5A96A58FF51622672DEDE9889564334C841625F5A0053E28EB4C253C1FBAB0C526F5C76918502CBF76CDDCDDB8DBA2CDEAE6653F6B885D678F4E495603591412DF7022F3A80DA638968EA9506F66DAD3D3BD10C06EC8377237F6CA2C35B32E40C989ACE1B51C2ADF4818586C01B92B3FBAC7275A1A2AF8F6A75F030D99349D5229BD87181B6A033B82192D686B3177EB51A07EAEEC2DC4C6471315C9D9939F613F7BE64F48C9050C0EB4FAC15AD553D3249CB9D8AB8EDBB1E4A97E1B8C5EFAB114DA0177FBB12737F1EA0828A0B6C4F1F67E2F5B0017183D07A77ABACB823C59285B730AE0FE574567F4A9FBC638F21CC567EC8F317C0E9729B21D82E3DD8169CC55BC67D2182EEEF38349A3AE589A4C3970B1D9EB9FB6DD540BAC5CA72EA0DC5C88FFAFBFF6B5F1F1F5C33E2471342D42F4483CE4BE0161B27F3692CCDC98AA3843263BD74B93B9198A768659787A19F3369DCA71E8BE2F861A3837F095D84B3AF06A780487660498A9723609BB89F368D2B1111F61B8188D54C67DF9C9DB6C742553A133ECDAA1A4DCA5774A69C1B656834C4ABCA3E1A402DDE6DD2C21ECF9E50D861CE2F98439990848744E7B0441B5A26F43E4C9515FA65F163B85DCE55DE645CE14CAAE06E95C1D7FD427DE8D440806B2E2C0F92C1FB6C4C4D9C6419821D4CF16C305F73B80F3C4765A6C4120106A530C2371921F1D75DA16C460A0197AEC0139B610F5C8DA33DB072A933180C5E3D30541B6DF54C19CBF101BD0DD0AEE88D75C54245DE8BD88741979FAF6A075D6C8DD98FF3F43B7EBAE04AA10966DD915C41397D1C951754DAF4621C59FBA51E13900218B12D1DD819D811909C31FAF7209C5E4ECFE8592C2F53C5CBA07DAE50EA43041F1E1823B0DF4A959F763D9888721550C00929C395D7202C452AC256A86A996C0758AF340BCCA0CE7F474471ED34A49F99584957FA76C431DC8963A22C640BAD8EBABB0E8D73570F985A374CCF137F7D6D24E65837C5A822C4BEB8B065B408A962D618A5C8807A524CFB70A18D74FC5F4CC3C38FE19F613A9083BFED79A806B00825CD07DBFD119BDD7DE7EA766F6B988E631E4D7F5AA614F43B3DA3DCA03DC8F63FA51A9A07D325B9A2E4AE42C3CAFC7BA46479B398E770A9D627761F0C0BDD0F51D42420D2FA9188339DC8BD15ADB83C816DDD5D884496744D5F620A4382F9DF60CB6EA326035CE8B0E38AF6DDD17C5ADB5AF0C091DB487646DA758B6E464B3564C452FF040D84E1A50ABC4B4CECA7F54C27ED31918C6DA8F5746CC02D58BA8E198E62C0066FFCF449DB78ACD9FE94A2AD5", - "572D524CE030EC1E68403DAB418C05D2322A3B824576DBA8BE2829F17005D7F3" + "DCF4C1739C9643E96A613496BEF0A477B097D62A9E4E93B0274B503E5A322F10C4C019AE18EB80C136ADFBC95489EC340E59221C12013A0525BC3C5C7CB56C6283AA12E2B058B9A16EE748C1E613A2C03801E44E39C6989421A6529227BC811A73B2301D981152476FF6632411617EED110C5DC448C8B706ACB48D4E2781C3904053817D07B56E9A2C24A3109710208842792B67E2B5E2B576667985159694CA0590AA4B0C8978BF5FCA96A725CDD10212AE92556BDC000BC77414D20BDA257E5D559AEB4BC75C0652F8C5834167749E589F2915A4F9C406F520869F234BC32B6C72C57E7297B1C5A68497A4C13B53255915B372406AEE46B3A7B418FDD439CCE023222BCAE78C9B405A396D665689177A7AD360730B370E69A76A56C4228A9089695D0D7C43C6D042AA01AA2FEA7025C391253906FAA97ACCB74149F4C44C902C0A6336DD76347578C88058C4AE7A54908A853745971C7A0365DB8CE9433A1686C7C7D16840F6725B254A51D2A8DC659B6A927B5EC074352BAB3F559DB71812E2DA045D9C10B13A1784E46BC7E926D018145D789B78A7C65B61CDD1324859F30A42A168219B1D5500527DF205001D4D5EC66534FB33B8410C5EB0CC0EF15FA344723B2A7B4C0A520B60562D341486C3103A329332989057DA75274579F7A6AA62D51EF98A9E931C5654AB126104879231C4C1B43E2F37B3E7E18AB13A352DB65367C392CA6721A43A2C1D2B8ECFDC5F59150473E2659FC0C57CDB91681C28DEB5292C376608497D87119F85D2A994C48AEBC8166589124D6B5E20E35E4E52275138AF518B19C37AA8B0679B5DE98EA61381BD513535E7847D6C9C3FC58A6A489FDE1C33456AAAEAE92459B5BB4073808F4C512CD8C06F99326AC2701085C711D78D8D41916AD93F63626D2715C1881854530453D69B9A86448A50F1809370B69B645DB90B04AA27A997A9BF1C009374049F55B77497E6AF622565686825DDA321D64005D4D457308864E352C6FF345B17A57FDA64022F05A80CA61A644BAFB7906B38F1255A677300739A85DBB1C0ECC0C3493FFACC023F3B9541D217DD82A4185C6BD1B011E8B9C4ECA71824651B1AA41EB07AC5EB07B9119374984B99A57307C5E608989A201AD118C1A06FBCA614144C8481714B77D5B821CC0B50F80C91443A92420DB8109ECE0686E00AB130DC67C7A867CD3A27A7BC27F3AC19D6159F3D0063F8DC11FB841AD83BBDC8A1581C69C5F9D01805500918C496F3E48F529112F0BB89C495599E14B0D27B1D68C77A7FD24E4402A5C93C9F81040448B67A926C8805F9AC34990F0B131F5E8A4A09E77E9FB380B62A5224030ED0663E05ABACB64332ABBB4D8816456E5780F69930C51355A3F70BAEE896CDFA61A1419570C31341DBA662655D92B507FE336D1A58B0702C4A98C2965E4362FD56147B299E5A0B20DEC6158EC8874C25578EFA4F228BB73979208AC0A4FF1288288AA3B2F57C69D33790F7224EE769ABA0406B035A9A4C8C2812CDF321B74A875BB0B9041EF92E0D27B71A3602D6CCADD882568135AEC5800D65AC16914B597B526E9C83B59CD2AEC3825A24AC8E9ACB9E80220B97881C9650C2D3E496F888265D60747AEBBDF18E7A766E042F456472C765A758B9AFADC7DE35B8F9518DF30B791F178A7F57", + "E895B8DD5C297C811D01281446C44C182738CC585083B068A5DBCD5368C82EAB2141A11B01C28BE800CA932356374813064CC1A60A72E5F4955EB20DF19C9060C9BF2B0B4E0511116F4A49EEA604D6633848D264BEF77A35F643CBAC92F5B25F686011BAA875DF33121E84CD6EF51F0927B3EF4A2AFDC1BB071222BCEC47839875379741EEF209D3F5118CA7AA103A11E738C5F881BC60A67F88B6B47E757A32340EB653C2CF3C6673CB41E843CB4A0875A249851CB7CDE5D87A4917A5F03C558F44451E4382D4E0082F48B4DE501B813270DDA80903C81409EB8470D16B52AABD0EAA8ADA7AAE24B919CA95458334A4AB566B44F865CC78C9CFB8214D48855D0413F2EBC51302014CD99129B6BD8AE11983602D1F05C425138D6DE17AA1F8700489483D206BACFA4E5746A6CED9B6406785BF85C7252641566511DB8C0F72AB752382374C72365E0A9548169718A910B29B6687AA9966505E86137FE845A94F74BC01443DC9F81B43E10E1D7A7265E04BA4F7A733ABAC6F6316BE92292B942E74D04DC3419385EC3AD1C3A10BF97DC2B259DED665DA7258342059C2F12226D46572EAB9ACD9740E779406A73C7893AF3F1C027AC37C5A7451A6A87730B105E0AC9645BB2CD1D2188BE4BE3FFC9BE5B956CA460B50A40D0CFA6BB69107DD1736494C7AF59148C296655FD0630BB14429B83F1F057AA9208B3F11C05B29CB1EB1044FD73AEE659C2040C2F4DC8AB9F0664122793FE89C2536869EF71F80629EA01230EC7648977740D6B11A01FB88F8F99766692ADD588C55591A61634B527909DA61782E995718767D20614175BB1C6FF360371A1334D5B820AB33A03C582AC5163FB606AA489C29385DBE2B206993391FF37F7C3B8B265939480AA01A451AF40C607C18958891CD8CC21984F09426B20570891E3E090DB6422174A03F8D151725126D6C246FE0AB0232279FCEC27415A417CE6424B70B3201AB3E6F14AEDC9A069330AB0949A30FDABC6C051FEAD73705F2645684B7A78654E0CB531205C3F00780F218392C338DEC8566254117CC186A3412AB43A237F4306D68634D8EE624B592835A37757BD645C79C8EDDDC5A33773B6B086003654894577F59F6BCB46731EF66A9A1B96016E94F87F4199384460E02A4EC37A1BA1546106B254EA53AD6B47869F556BB88BF5012CEEDF61C69F3551465222CB758FE61BB28B541EA4CC28F71AF5D115B7FA256126B0329C579E85425B3C9A942B81FF8666C57D20FC1443AA6B5404B477240271ABE3566CD28C0AF5203E6981D182B10333BC0CC62CE7F124CA345A0CF55601EC92A14D7783A5671054C14C24533754BBB12947D2A4B24168932CED48E69E619A806C3C1DCAE30495018F08B02E66749E3B80F686C32A9833F3737154854478839B17ACAA4EBA98AC57B1879BC1E348CDD4631091386DAA38E12EB1DB64AAAB17C441C8A155949C23357552EC1A4E7E568823804A0C0B35AAB0902AA3E5E18C478D48F24A2B4E205331F25AD5069AEADF6C293D68933E85B27E2158FBC4841BB873A758999D1517A87A4DC89C42DCC69C2D18F8C090D1B3452411451307BA7C08C602F9754F1C45B6A376AF35B36CF327FFB9586A8D23EDCF4C1739C9643E96A613496BEF0A477B097D62A9E4E93B0274B503E5A322F10C4C019AE18EB80C136ADFBC95489EC340E59221C12013A0525BC3C5C7CB56C6283AA12E2B058B9A16EE748C1E613A2C03801E44E39C6989421A6529227BC811A73B2301D981152476FF6632411617EED110C5DC448C8B706ACB48D4E2781C3904053817D07B56E9A2C24A3109710208842792B67E2B5E2B576667985159694CA0590AA4B0C8978BF5FCA96A725CDD10212AE92556BDC000BC77414D20BDA257E5D559AEB4BC75C0652F8C5834167749E589F2915A4F9C406F520869F234BC32B6C72C57E7297B1C5A68497A4C13B53255915B372406AEE46B3A7B418FDD439CCE023222BCAE78C9B405A396D665689177A7AD360730B370E69A76A56C4228A9089695D0D7C43C6D042AA01AA2FEA7025C391253906FAA97ACCB74149F4C44C902C0A6336DD76347578C88058C4AE7A54908A853745971C7A0365DB8CE9433A1686C7C7D16840F6725B254A51D2A8DC659B6A927B5EC074352BAB3F559DB71812E2DA045D9C10B13A1784E46BC7E926D018145D789B78A7C65B61CDD1324859F30A42A168219B1D5500527DF205001D4D5EC66534FB33B8410C5EB0CC0EF15FA344723B2A7B4C0A520B60562D341486C3103A329332989057DA75274579F7A6AA62D51EF98A9E931C5654AB126104879231C4C1B43E2F37B3E7E18AB13A352DB65367C392CA6721A43A2C1D2B8ECFDC5F59150473E2659FC0C57CDB91681C28DEB5292C376608497D87119F85D2A994C48AEBC8166589124D6B5E20E35E4E52275138AF518B19C37AA8B0679B5DE98EA61381BD513535E7847D6C9C3FC58A6A489FDE1C33456AAAEAE92459B5BB4073808F4C512CD8C06F99326AC2701085C711D78D8D41916AD93F63626D2715C1881854530453D69B9A86448A50F1809370B69B645DB90B04AA27A997A9BF1C009374049F55B77497E6AF622565686825DDA321D64005D4D457308864E352C6FF345B17A57FDA64022F05A80CA61A644BAFB7906B38F1255A677300739A85DBB1C0ECC0C3493FFACC023F3B9541D217DD82A4185C6BD1B011E8B9C4ECA71824651B1AA41EB07AC5EB07B9119374984B99A57307C5E608989A201AD118C1A06FBCA614144C8481714B77D5B821CC0B50F80C91443A92420DB8109ECE0686E00AB130DC67C7A867CD3A27A7BC27F3AC19D6159F3D0063F8DC11FB841AD83BBDC8A1581C69C5F9D01805500918C496F3E48F529112F0BB89C495599E14B0D27B1D68C77A7FD24E4402A5C93C9F81040448B67A926C8805F9AC34990F0B131F5E8A4A09E77E9FB380B62A5224030ED0663E05ABACB64332ABBB4D8816456E5780F69930C51355A3F70BAEE896CDFA61A1419570C31341DBA662655D92B507FE336D1A58B0702C4A98C2965E4362FD56147B299E5A0B20DEC6158EC8874C25578EFA4F228BB73979208AC0A4FF1288288AA3B2F57C69D33790F7224EE769ABA0406B035A9A4C8C2812CDF321B74A875BB0B9041EF92E0D27B71A3602D6CCADD882568135AEC5800D65AC16914B597B526E9C83B59CD2AEC3825A24AC8E9ACB9E80220B97881C9650C2D3E496F888265D60747AEBBDF18E7A766E042F456472C765A758B9AFADC7DE35B8F9518DF30B791F178A7F5723B32723A44FD9E241EE028260390984E116CD064323427A8B6C5522B88E4B710E8C8283EE8787183176BF4AD28F8F2EF2F01856A2EE84A9715D103158E05F00", + "1598C20DEAF700AABE2592E50832B9DFC33CF78B8BC71B0A73059F3C01F8DE719F65A0623734281CDF12E1AE6284AC5668B8F0F758A1216136528C00F31810A293C05D4432BB63F3CE61239FCDD3FF45DD1A50FFD2DB04215FF566CA9E9AA9E37DA8E78BF279A08301AAC779E3752F05AB33D2DCB7751EF3A18D99B531ECDB7C0986B35C0AEF64897BF24A97E480C05988A136396F9AA29EA73DE77FF41788199C207829FCD2DA68C2DAFA3EA3A0C6783F9A1678F5E6E81E84425D0AD26A8A84FA09DBD27D3C8DF52A54721EB08ADF7DB3BA9D877A6C116C408B5C7BF9C01C0EB61DD9F02D645A4A744ED5AC75FCE2751C4253693912D3A9A71E469A3A7234CA288DE993FBDA9CAEBA8A53658EEC19D8950776FB332DD0D6F64DCCBDE238F2E7BABC82BBDE66FB202A88D22EE1C039AF0921F893689B23AD28D3BA7D8DB87F5AC229733DAF12FD5B10DE452035D7204F996AF51B0F0F7C2A13BF4255E9A37157F26B97BCE1BA50A72B9FC9FA166CC8D499A1BFA96BD4A8EB5FCC8659C8F6EAF381FB968835440ACD41D80450548DCDACAED400E0EE3FB9BC7C180B53FDEDA20F7EDD50B467ED082F408452314C42F6E3A77979379CC0DD83F1FE1A8A9DB4DBE0999365B14B9D75E9AD5533CCD519302904126C18ABF5CE0EBFF5DCB90809500F5B688A9AF48D64FEF6CC2BEE955906776F3BED1745CB8CD73063F5445F696A073C370DECE09FA071B66DE6B90C9D3B62D94E44F40DAE75562F5F722C55C13CCE6059A9156DC917A7AA2D28887C06841B01E48ED5F1E1593FE38BE165716081E5287B747DC8BB58666D65E22AC733CE770DFB835AC63E27B1B96520FA4D7C4669131132FDC92F8FB5B4562F72A93A824E3174B4A0CF04CFB1CF6D425112D7F2DB61E8C8FA6E983D1B110B1BB508A6BD37838756F9CE5063D874E7E189C9CD4222A64BD528F532255DE825CD2B954C9273F7A1EC6A85555CC13DDF16D7236C7839597D7F366CDAEEC19C62269A9D2957550D9B5D97CC3AB315353C5A5EB945DB6F9D8E7810A28669C5E4DB3ECDC657139B67477C289043024CA1B37E2305A206FE739075A562543EFE710663F7B479AC9D5642545301D41A655379B31C3CA4B178F23E12E80855176AFF78325C416EF6EE8665E5010E09DECC991C061A7BA20CB597D4D01614842CC918D0EFB314EF1793C50C11ED3D2A649007000ED87F5D76F76ED4AD3B7D218142433423AA61B548B0CE5FEE8C11F66B7712F6D26BA17292BEF6420DDEE9B11070DA1BD93A08AE092521C745B11136B4F9C6AB5ED7722236C4E776E90ADE469879B573ECB3D4EAB2520D401BDF6352C8EA959C9210E2AC7CFF50A036D77209A82843614D5870F20479FEBBF3B68CB5F4B3B6823DD3863BD92A836358FC1ADC595BA0B6376D7B1290D7EE7D615A2457901367D988BE8B5208F7179FA00C0AB64CF5ED6ABBF5FD136D6CE9E9BEFA9E8CDC1AF1F3AE9C95FF5F46F98CC6619A3A664170533A589354CC7BF24196EE361924D48F5AFE65F70779D4", + "6F46D1B0169203883DDD06BDB7F4563B53C742B2E223C2026809CD404EBA55DA" ); yield return new ( MLKemAlgorithm.MLKem768, - "DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D1602", - "21015917953F3926871D0BB9BF7802978493FF5A24D684CDEE1B76681902FC8A9B63283C362C33FDB2385419462F4AAF9C6A9588F06A5FE52F2BC923F87123B0099D0A2B456D350B21050F14BA0EC2A56974C9A1403518330C809DF69966D55FBFB70DA27136DE5793F7E73C71ABA60A5906CD36C5653A2BECACC4459756D9E37E14E6587F40389C0895E94BC5C105C4A394098F3A5F27EBB0D4E5B338466F1C964F79322E0CC9AC17B68BD6D20FE77996A740ABF95790B69168320C320BA6602B9624CBF12C84F549E6C40CCFEABD939A934E46A8C63CB627E499D9936C8BE3927294523179224307872F9B8667B175349BA867CABC3DAC47A48A46BC001B647B7AE03878F55A7029894173039D8D1C1F9F49BE12E88743DC709F101280662EE604CB25E75215A570D3FA03A88867E8C4A84F0351AE051F90E36441366714545236CA643BD8B85FA947ECF4A536C13DD7CC6BE7485405C0CC204B91244B364E7A33A60494683A99F5E3C21BF57379061AACA63E569C0E82164633A691BE803B2CD9464996C050323C21080E8C0822730B904FFA7A656C1B568708168A4CB1F54377A02542C42694BBCC38B4CC27F7B735418346FCC8D09B52E89B8F88627BDFF73A87A07B58299AFB321B0BFB1228E53DEB899AE7582066520CC85276A0236276738B58231FC610C3C40B326C4763AFA309435B05AF1C66E84C49430B98F7D4A76A843A627693BE3A67F57C20140B94ED694A1F671C0FD378DA3CAFEED30E5C366C3509AB1E14AB1E08D029A18BE1200D1A8916A1F011B7D0A9A47860F0B09DF996939D2377BC53B7E7CBC3A9517C31A78BFA724B6DE96EE101782C0641E2EA187375B8E5579426995BAF9C30466C4160780F8900867DA89944B1AAB84BAA7F987ACF2AAD97ECA9C222BF2C34BA5F8BBBDEC2C434E43828696FC38903F4C3B7DDE727E1D36A71F9BDBC71C878A3399D346669924E1C3CC2B2AA0DB08A0F30FA703DC308E54857E4142846F9235A48538E291D683409E25CC5AD1C56B690039DF5AEEA596F52AC991E1B3D16E809BFB723A7004A0DB59F0B40885189C88D4CBAEF3ACA2951314ED90789E366EEE8AEEC84798FE931CBB3A42E847870ACC06B3885C0EB2DDE149DD802C1F32953AC20CB87899C0855B2E1D6B8B5F6929D3B9603C73BAE5C528509AC1FDB34FAB2C63773C44195010CE80A229696CE075ED4409A0D0CAA966B20D6C356C4F44272E1501B897159D544F34B7C3B0280D7FC54E223AD865307BCB36CA13729FBD36DB285CF5650C7FD451CD8B305280338C7460385464672D73C5D30A4301A611DE6751C76CFA0BC08D8958F9A170C6D0ABD75007327E891A874181BA87A9260C14378068F183EA9E1CBE1E571530856D7118D9F1AADE546691BF328E5460B114A7DE834B2B218B22BD4C83A3A4580B2C59B325B1BC68231C3732F9AB666C726BC4471E204800C27783DC8BCF6B6315FA8ACE005CCCEC92116D7B34490880452A82098B692552279609D073CB0FD58C82CA888673A093F4696F7A4CECC169DFA336FC736BC995615496B9FB527C83A6192F893386C122B6C5C67E51352A7CC6CA4A7ABFC4006E6105DC7838229D44387C971375933DDEB6980B1367D597D82860227EBC0962198D10B10492469F083B09D884C6F9C80AA0035B3B342D1AC1C9AE7A6F5AAAAA9037ACC496C49965CBAE11C72190374E85C9D5060B9F04D29D289A0D2B59A71C6514B47A6360950D2285EA342F618293109719448633A58311842CA4D66963F122252E0C4D1B3CBB4153C23C2C52E602A1CF47305C6994AF0C27E804C5AFB464EE5A899A8607880865CF57FF8C1C0AA063E44F25AA751B52968221DDB5F81B87D71876615C158E0A0275191BA1D7785C7516A3C604871261B7C319C1688153C9C8EA9E0B14AB708E2481A1FDC99C0D912D8C16B308428BCF28A47DB1F79918406981409405C00133446C30D2CE71755B06303BBC91B2A0AED4583244596F251C42F2B3339B15E74663816EC5A8CF920B25419B7F1435F158ABEBB6E4165C055166913074A48608B51628115E78A4ADBCCAC736712A304FEF240536423D4BC25B3A32C863CAA306744E570360D54B555903982B00175436E143BCD6E62A23C7907203AA3A84670DEDC0F36C327D8DB6936A34487EBA771B48F15F6810780B031705CAB2146D81A7B9A608C6DD1134D8C7D515CA6CC91131D1A89D2B18F46935F03A990E2A72161F720FD75CADB62B4FAEC98B751BDCEC389E35B13529AC319A62EDB44484158A1099B4BF0BA2623D19C5F09338A042BD929683C6C4E7010A770F20C81EC1266898520C27F78C663B43A9B72F41BAA2921436986AA1A8D39B397A0F79DCE4CA356837C36F476EF4A849A074D84A91CFFA66958B75D99B729F61742E1C117936B55006AC8DF970F80229B479547A37244D465B800F5A773930B8F2445205C6AAFB9C5E44C4107B67A63F97DA51421B790311079002FF2A3C0D6896A9386A9C2CD2E09CAADF9559327370B180ED57236D24810098A619BBC89CC2091E160AD2364CD51466BEADB68DAB41861A4A364BAAAF0C33C6770CF71A03021E8125E726B428647A5C3AE88B536F9DC46D5A72DB7B9AD6F622D3251C59BD544CDA92AFAC7CC2594A93BB18350191408E67B39E63E7E0329C3398197DA4A229C3694947455DC2B901431C8CA6C32051A2CF416850301631972D3C0B3E1612770F063039917ED41C517669503572AD83709539A4135CBA39BCAB3EF170645B231B86BC4F84892A69C91D2F73CE08B1E478A93F0EB067C777E373926E8466CF1E0BBAFD05D6E29A7DCD730534C5D88B31D7C7B93CC3991A4150E2218729040A4C76AA384309518AC1D1605CDB1F5A6373C8DDE597B10B60D752AA5FA90123E57290715A0AE559DB657B7ADA285761559A1634253F122EBA738370363D0699C3007CB39C04EC27C433C89228FE664B72661ED144E5AE2CCFD02BE9C25A89012CC4C6543962507E6485426FB60DA1943CA168B25341F8AB51490FBCDB762CF08A9622AE9358D912D7604520281558CE1CBDB55CDA6255773B463202B7390C093A4AA3CD1C254CE54167E82808D40B496350E86E97E6C0288383339C3451DBFD29782072DBC0C0C317C716511AB9EE4BA4C1385C9AC326600C1D749B35429649B06151124A1B5212E605C1E6839A07DD363E567CDAE535C4A54AA85C728E9B496EB554307051011288E49A5BC30B8C34DF8355BFF525095E557427BD1041C5260E664AFAC328F50CA91C06612DEFF490D16025BE307C628551E3A1503B1D1B2C2F92108D98FD965AAF9949B00BD097F17B8B0631B752A02D85CCC07627E044EDB8C61E43DCF8A864DFE086D28C2D72CA8B428", - "27FA207180726428640D04D6C7581B1A959D504177882AF4956163526A84757E416CB21109A69FEE7794B03580CF4513140F0DF1E9850EBA999103B547DF82F0DA7C5D42EB9A665A45633C72944331ECD86AB636AF3956895B2A10981126BA7C853EA010E7902D07559269E15209FD1F70AD84F9011639753AC9174C98897C2965D47941B26C4EC1716E794756A24949763A6CCB410A779116811D4D544D12F19416F1E2D10E33664905840110F7E05BA356FAC2121E0E74B4B27A77E70AB6BA99770A3FCDD4E97D1B07EDA187C6AD20FEC18CF897D2393288A2FAE08FE800FBA5C2541C62E30E3E390BE141A5468A7C7879D1533F1DBF8A5E37861B889A28369D4495ED3B8969E8DB21498FA8B8F4EBD971D19586004E03EEBBD9AF1660140199986C2531B2AA23C6EBE511F962E35F18F730892B72F4084CA29BBBDE04CA6BF722BFDCBDC329BF32A34DBAED2EB7706153F17CD44205A9A01A7BC010D857ACF4B4E18B9EF9502A8F9739A5199DF95F65F271983E8668747F399CB72ED7541525B2F7B2ACFD1559E217AF2EFD76EE638F11D909DAD84FFD10F5E7395B5451800F0744192240DD2A3A8C8CC720B8EB1C0E8B0F94EE863C02CC72384FBE527BCE76E9BCDAA53D13BEA3A3C983540B86344BD66FF650A19251C7F29724D144612DFF8CBE9C80F56817C48E9A6C189AADD20A5C4E21981560D7FA102FD5138DD5235D75BD28A139F0A8BB6BC0D4B82E3D816A75AB6916DB36C948D78F97705E4C0E7FD0E768C165DDBAF51BB103BFFC0C43324DF12F6F4722D11D7CEB3BE089103AA59419E114C3E830445C5F68D016C861EDCA24232C60E61FCE57D8CBEBC00ED17775701CABF02E3B57BB83FE92249356719F06728A107A8E25AC69E947E42998B285500B10625DE05DE0E18842EE828C4203C4AD8441336FE08B746E6F72206D4B9E9C6A08A5028BF7B7FEC2051B9799DC8E0DAA1EF92CE80B41ABFAF2596325F67AC0833589499E2418C55406D40EECEA4FA122D8509107B5787455B8A58A0E43872AFCB7F3D945CE1DD98F95706765F2108B211EE88B1B60453879DE5183025E0904DE762E219BACFA402400489C0DF991E16BEDC388EC3B1587AF497F212B8136F377F8BE3BE43E5829C6B4068C0F498F26C6A6B056D4BCDE4123B71F96BB8DC44DD435E34FD7E722160942FDA43597DF6850641303AD72C8AE73D578ECFD32A6E68610CD547F4849421C3468C810D174A0C372325BD3312B6673BA791057AF7B2791A36B007F5D21D53B4D9A8ABEC826591869146D2CD819FA1E7B53F194D242B85D157F98F5DF69BB50D44A31CC789407F2BCA0C93CF8AE5BF6370D679638E6D4E042B785394AFDF9015A75A849559131DD1B64987D48C9C6E8C7F84A2D3F356EEBCE942B8C1A68F19B1EEE3AE01AC807B4B2EAE66396564E3C298781943F0562629B992FBC288092B046E9BB865D97CB3B592A18B56A48283900C3CD39EEA21CB11D4EAE3E3CFBDCE4042383B5DA5F479F9F667C2A8C8EC0D461A5FCE0", - "9D83535A535F248E2F90932240AE440E670C859C750AA41E813C209892B9BE91" + "073262FFF5AC037692ABB806C1B416C60926F684AB314A0C90A90B0DF1382F701349A228EAA7911E37C26C69A170782314A928C5E27445322A17C81401D71BAF1B71A63C08DD0A9842DC9A6101BCCD91C73B772CD54A3401B435FDD929C84C3A884597E15BBB47D21D4B933E86E940A554377BD90271E3B5DF0C0D06E3AC1C523CD0A36AC025CF122C619957C3DEB286A7435660D33665466644DC5F4097CFA7B256804909800B298D31993E2B89B024337D58805AA62E8454AD4099448C6C0C91E93DB3673478A35B89540D235C4D022BBEC35176A29936EB571F4660028109CDF825B979F5A6BA51023A8432BCA84A6A90CE544AC57A091055C1099C71BD6604C06C2515130C1A55D6C9D31640D4E9C2F9F1A4C74ABB6701B9EE36238D40B6D682CBB6623AE7665A0242B140F4578122BD5111197B51A7F860357EC6ACE05103A035472DA73548F51B1D887C02042600D84B9FE6BD11635AE8D3AB04B98FDB179EBD148596A3184EDC1210D888DBCBAA1131AC87555F427A86B9FA2CB3EC6F04E3C4A6738EA8E3714A0CB99E09B64697B1717C938CDA2C8E710CD380A12CD988E5CC5F571C47432007A0B3CFAB55C2CB96C948F3829505B5142B25502C7C213027E61793D34844A28A8627AC6BE9263B0EEA0A6A5CB90AA3496137A20A445B93D4605BCB83AA371C2F5730E9C20A738665007D57BB249692AB513BC66FD04486F05C749A63C5C060442B971F67BB1077A0B153986B28BB2900196753CBAE833B277268058AD9680134633BA4B7A4315344166939E9C15629B3A65649E8577289063881B4ABA3655FE8EA0BC58C7017A249EDF43C27676708411949567B53886903B8716AA65D9DB52638F893ACF261BA7868ADB10E3D57145A475C9B8613D73378F0A285D5E29D817592123BCBA8F5CE075BABB112BB0688B311F35ED6831F3F4CB062064B5CA5363267AE9AFA9818E71F6BA1987E479DAAA414C0004BF738445AF250CBFC8746E85900DBB972834F40D210672B3EDC20912961162248B084B99E649A67637A036B974B04C48D750225835C354B92939744699D3159818B54FCD844C64A5C57D3B559417C14B2276C38B122773C99682C6AF988214472399719A86362DA1B1CE6812AE1714F70C1B125BB594BD4CC55F99F3F30145CA6CB2A66235BAA381417C35003C7DE867BACC81BB3543EBD1339024C4DE8CB3B0350C98477B5B4F7AB83AC519C7438DDFA3097B70FD0F1B2E6C220F67C3CD7188678EA1B72267FFA4285D476517590BED240C0A81A97786622CF1B101B012F132CC60015A59DF3A6C4578928F6035A662EEB78CCB89552F165C137A60256464501658C1268AA70B3A3AA665825840EB4E015C558BECD923D32CB8BCC2C28A3370A4614C4335574BDF77446B34D9F5A7E9EB89738148C4AE56D9B1C829A6935209227682BBCE13522D991B4D2625DAAA679B4DC6A118A672D5C247607A9620C1C88CB7600852E0C394005F45C54175BEEBB9BCB3C3873622501F0B80523294F122C6192BF5E53894A64A733E830DCA814EF7BB62BA60B667CC169E0A165528B46ECB2980202E2AAB0EA5961168C6933C6240C85B090801CC0731A0FC70D09D83C9F2C7142F2C5ED6B7C7F553439E8E45B93898C12ACFF89DB7D67EE875DD9834F3D07B0", + "0418440CC60A0D376B474C2435C349E16051F96C6F93E3B7C2EC6BFFA352B31BC6F0D23D9F592EE3CC9330B49E297A8B94DC511825BE4DF459B35173696872CCB13F78F270E35A452AC55DCB0A0E01809012539B990195CA6875660B20DCF00040048EDA934CEEC501BAF21A6E54B096C8AA93E142E98A7C6A496663DB9317585CF731644AF55DD3C34CE8988E48C27BB9B28F5270252F6A84AEBC54B0441A7099717AA68DD955B9991C533B67C6977851EDF611A844055A47B5FEA256745C34CB1C511CC934EDFC7448D5B8E0D681AD6877168815FCD4740F1228236C43A23A7C208CAC0D8BC8F4855049310B5C06A49A8706EA134B4C179823632B40489C270814D102310C35B76FA5272BE18497A7B6B5897D9FE7246D3B940E25AFB7C44C41DA25E4128948E78CA8D11F241243EDE3A691D25DBB4323A884747A8C514CA0AE4A89557AD34F92BB414840BBE7AA5E3535894BA72A9C1056A20639D7265D5199922F3C17EB7A42C879C25466BFB5D45195CC898CA8BE53A01D1864C87D548FD4E3B203E51CE8CB140F061654085CACB3CDFF778DC11212F4A50107A2C7003D67A92B859312582C3459A5B5AFC02935F8B462331A416117899C32321670710668A8D15A8B5F73CD828231446A19FAECBBA8849DD0724879D008CA87B0FB8B0152541CBA86BFC7C4251F2329569396E6C1A5AD750001117A5B3486E8F67502BCC31ED9BB28EC224CD1C7E73B6F664566ACEA3CBD7AC063B0AB8A4953A9B95D920A080AB64FEAD7C7A9B304756AB15F44C48D350C6A6A8162B95CAA698B3DF824E293B7EDA91055686F3BE25BFA4006A6AA2200D27D98E41A08382FFAEA541D34A3E63984A9287C2A540BE4401E0EDCCF29A4285313684A972032A047309729D6BA4163204F33E8A592DA824EC281CE82244D24BB883428FF9CB750816C307B6084CAB23EF6327D2233241A2B80069E520C2E6B706EAD3456312961B9167DCE049F7014460F769F22CC3CE8C05FF6D14C2209BB0C1AA0DEF85DD07303D651C5ED3277E284236BE570C3E956FC845BFEF650DD9A6015B2ABE33704C93B8DFC4C814A47AC8F79AFE4E2C51B5A4CF3C8A1C0C828E0529A6B707599B544C9336AB4005FC076182AE778E20013AB64A6F28736E47802AB63C33AD51ED994724AA472887189D579BA6BF802A670CC86210661F3A46F1C93E1EB3CC1E944F9C479E4A48F45E08F8E2753562477E9C350AE8B3E9DF32589527413D154448C1BCE4B55933B8D657885B662672C3743C0F17294276C2AB5703D0324D36AC50635424C3439DCFA7C2B3009E4B934FD866DC7454130445F1898B5DAC33DEE7A4B69BB0ECC3949108AAF59888D92358822522D8603061BA14FBBCB681FCB742DD910EAB7A4685C1968BC1C55072800625FB476B91963AFFE589168D16AF7857025B277A702634BF7A2625943A219455F0139C36102521C0F795363B2C9902BDC51517562FF541E04C12CC00C90B224C32E7BCB0DF15BDFA82F56683ABEA2C2659A35331C4625C2A5C0D1B9B036AB7C2A879E6531F8A08249795E5BF2C920639F50B74DF2F2946D1399AB18049C9107B6288DDA53371D18A18A72A66E167C14BB3D9E9CBBDA76B9073262FFF5AC037692ABB806C1B416C60926F684AB314A0C90A90B0DF1382F701349A228EAA7911E37C26C69A170782314A928C5E27445322A17C81401D71BAF1B71A63C08DD0A9842DC9A6101BCCD91C73B772CD54A3401B435FDD929C84C3A884597E15BBB47D21D4B933E86E940A554377BD90271E3B5DF0C0D06E3AC1C523CD0A36AC025CF122C619957C3DEB286A7435660D33665466644DC5F4097CFA7B256804909800B298D31993E2B89B024337D58805AA62E8454AD4099448C6C0C91E93DB3673478A35B89540D235C4D022BBEC35176A29936EB571F4660028109CDF825B979F5A6BA51023A8432BCA84A6A90CE544AC57A091055C1099C71BD6604C06C2515130C1A55D6C9D31640D4E9C2F9F1A4C74ABB6701B9EE36238D40B6D682CBB6623AE7665A0242B140F4578122BD5111197B51A7F860357EC6ACE05103A035472DA73548F51B1D887C02042600D84B9FE6BD11635AE8D3AB04B98FDB179EBD148596A3184EDC1210D888DBCBAA1131AC87555F427A86B9FA2CB3EC6F04E3C4A6738EA8E3714A0CB99E09B64697B1717C938CDA2C8E710CD380A12CD988E5CC5F571C47432007A0B3CFAB55C2CB96C948F3829505B5142B25502C7C213027E61793D34844A28A8627AC6BE9263B0EEA0A6A5CB90AA3496137A20A445B93D4605BCB83AA371C2F5730E9C20A738665007D57BB249692AB513BC66FD04486F05C749A63C5C060442B971F67BB1077A0B153986B28BB2900196753CBAE833B277268058AD9680134633BA4B7A4315344166939E9C15629B3A65649E8577289063881B4ABA3655FE8EA0BC58C7017A249EDF43C27676708411949567B53886903B8716AA65D9DB52638F893ACF261BA7868ADB10E3D57145A475C9B8613D73378F0A285D5E29D817592123BCBA8F5CE075BABB112BB0688B311F35ED6831F3F4CB062064B5CA5363267AE9AFA9818E71F6BA1987E479DAAA414C0004BF738445AF250CBFC8746E85900DBB972834F40D210672B3EDC20912961162248B084B99E649A67637A036B974B04C48D750225835C354B92939744699D3159818B54FCD844C64A5C57D3B559417C14B2276C38B122773C99682C6AF988214472399719A86362DA1B1CE6812AE1714F70C1B125BB594BD4CC55F99F3F30145CA6CB2A66235BAA381417C35003C7DE867BACC81BB3543EBD1339024C4DE8CB3B0350C98477B5B4F7AB83AC519C7438DDFA3097B70FD0F1B2E6C220F67C3CD7188678EA1B72267FFA4285D476517590BED240C0A81A97786622CF1B101B012F132CC60015A59DF3A6C4578928F6035A662EEB78CCB89552F165C137A60256464501658C1268AA70B3A3AA665825840EB4E015C558BECD923D32CB8BCC2C28A3370A4614C4335574BDF77446B34D9F5A7E9EB89738148C4AE56D9B1C829A6935209227682BBCE13522D991B4D2625DAAA679B4DC6A118A672D5C247607A9620C1C88CB7600852E0C394005F45C54175BEEBB9BCB3C3873622501F0B80523294F122C6192BF5E53894A64A733E830DCA814EF7BB62BA60B667CC169E0A165528B46ECB2980202E2AAB0EA5961168C6933C6240C85B090801CC0731A0FC70D09D83C9F2C7142F2C5ED6B7C7F553439E8E45B93898C12ACFF89DB7D67EE875DD9834F3D07B0B806AF8E3E2451BD2609D06E781E8D7782B5F5A7A3827390F89AF1144345DB681ABD75E434B9C7C69E0B9F600073E2D6761E7B33B81DD6C636EBE07641A9CC8A", + "BD8C66F480EF2CCC9D3AA349F020DA9C5F36999A62EACE288AAB387A2A1A41229BCE8DC1005F3F7A703398922F86E2FC5E4A0F9799C4C11FF3DA46A165268DE2DA7E1F79CE8FF15119313942AC6DD7DC0E1B8DDAA294B6AE215C2924ABB4440DD22691490D2E02C434E30938848EAFEA25DDB13A6B6AC9675D7A55982CCD726913FC82C00952FEE976A714BA341291D7F3261A20945F1F53104D56B3919926F851FB986C1894A8106F0EE94E0374ED9FBE193AECA2B8E6EC615DD39404AB16A9E30FA66BDA5E08A395BC76157B3C3931CDFD2AB5FCC7E2C37D2288EDD7C8EEC9D2D1CACEC466CCAD615D22218C410CDBB0DE79871E5C7947203ABE704C24616749E0CC0A892FBA42EC116D956CC5A33668261D43F40D24850DB9BEBDB3FD648950C13BE2F73DB6FDD31C8DEF189BD4FDA96A5ADB19109E8BA67E8D68BD0FB9FFD94A7470D8093444D5A0682099E9A6E7149400845540A85FD82B338AE79CF695E27A055C6702755FCF928CF1B78E78D7F73446BF446641AC69B7889C9F466BC29A3C32D99BC9D1F8546EA484D11EB26222FACF825A2F96A16C12031C3B2FCE0305B0473270016CE95EBD7FA02CFA5CDFC6F8FDAD31F801AB71AEA2C6E32524F5BE77AE1DE5F33FC4E61A2685A3D4E5CAC57B6803969B8F0CD4D42042E04B38F4F1C9C1AB8A994BFE2C5EABB66E05EF343AFFA4C3500E396609C035B23D6DB7A413A59229928CDD998414E0E8DB3FF7576EB36BD7AD03EFBA30466BA6384E6744A6F568AF579C097E71AEEE0F051A138E6855FF3DE3B83556D0C7F2A859C30B5EBA57D58B3E0D996180C06619F26F557261D0F92471600A8A473F735550E9E050C96522C3A2E98EB8ED08643695188A0F3171D6246D815F33536B2711D882B0358ACD95E630BB71FABB29C9B89CFB8FD16BC5231FBCE680D607CF82F1F1C30482EC014F43DE03688022F05C71DB110163A13BF95E095DDB277CDB697E4E48C8E1DD4D1762E9D06B186C5ECC41C2687254A02FA97CA9BAFCF113B6F5D4B99BFD89032EF09D584AEFA3F5A5080A23019493973DA877FBB07F3628DE93ADFE57FB09A0B95BF19CD6D8A563ADF719BA47E2CEE325B00B5756CE39B0FC9F6DFD4B805F5B33F61180620239AEFFBCA9C211048A8AA6055356AC9C2992022F6B601A7101E1E16DFE63923F19842C4463FE0F06ECA2158D04449F10C5524727821FBC4DA70DA0F2BEA5EB0767F512EE9FFE3496EB2EDECDE2795E1EA2DBB5FEF6F8D54E54A0CF235A4E30CD64EF015FD98231148E09DD79EE949A7CD1CA7B70E704147D1976ACEBC3E4D15596D206099FC915256162ABE59542BC149DCDE807C33B89150BDC630C9C23E24F2D7EE7D49BF85FB4C2B47E2F26658FBC0B93EB56A89AFD497D7895FB76718BBCC3431A5FB5EEDFB66885BE1374B174940C55124A30233190CBE636E0418C248D4EB63251E2CD2F5B244F37A76BC9B167E50221DD826E9B1EBA00536E992574C6F84DB4D526F40D29F62476D9C41E9C9763D88EB3718B91AC53", + "9D2EAC936B7D0EF407ED5FB1448B5C511C01607A90D61FC6BE72893DBF60D120" + ); + yield return new + ( + MLKemAlgorithm.MLKem768, + "FA0A403259997B18A17F48A725FB8672C4BD35699DAA1412DE7C09C0165836583CCCC03A59005CE7C890540C4B9CF05D330AA645A4BB5038672F3619DCCB427A370F437C16491A15A0C60950F19AF7599A1E299E6C40C828A2492D4474C9CC50A67C558351A8D57B4EE27A990982ABD3F935D6F31797E5A3ADD69C4C76893B569F22945B42E1413365C141A81A62ABCEAD2542837C0F1018C266605A06590C7A96296E875139FC7939CA1DF6C07A6F8271539AB8EAE8C25FEA4C313A590BC04E25E954C648732330726BCC3FEDC39F46320D82C9B20F229D211137053BA72B05CB2FC897212B184839AF8324A189B9A855C0B232447668D899EC675075D35FF5DB53E9322C3F3281622A05A7996CCB52159255AE012886B982A1E9A03CB1C3A0199A32001D75304068560162295C8AA8574ACC363D806356A9D388283CBD0D700C36DAB8B55874CDA60608FB90EF4609410459A5319A4F33AD7179329F178A6870BCD6084CD8B213A06C88934952FF75916987A738A3574C60451D70AF60C855D8F78C7E680157320938658F6A421F1B590C7BE87429B95F0B5A5178B25E3F2B61E9268D41486C05402423D12D529B2C8AD109ECC10D48E6841AAC7C2F0B22700985E21A4DEF6771F70AB01919562203925B16802824877142B93517733FE5922BE28638B728F6CBBF21D079A2A61BF1AC7995272031E076EAB6B68B12BEC782CC3C967FBC956C0F4C9345967D59C17E55C8926F342BC6067FAB55781ECA4D47016258C0B6A3A39C5EA98FB9F46745D52AB103ACF7D45D6488B91F872BBB313DF76247D297AEB8F87EE1C63A2BAB82EAC59F4F80CD9E1B845853AB0148A4F12A09FC9822180436BF7033C637CD17962B19472FAA98957B226C3A337A0489CBE3B61E2BB92DD0A390D54C5D56893529C75F956A415D3441F696B8423187C6B1C6A31C2C42F85003900540A21C00546B4AD75F1C001BC56443AE87A87B1993F5D18B4E1211100206A3665ED3868A510BBC70C6353DF89BF8B933D9762D499BA61257BF15D653EEF42CD737BAE25C03986644F9C97968CBA2BA7A8725172C78F15AFB659221115169EC08D0557C7AA996551061271747144C281C94181BA2177803BA6B671A13E406ACF5B474A0CA96D18A96997CEEE6082C218DB27C94FF4C55B31C2CD0BC4438AB719D1B1C6EF46E69298798986EDED0C83292A70CA0B061AA86B625C3803B6389021238457A9FE327957C63D7E11727D7954203C720244AA5D80F6C303DE49B73D71348DACB700B7A4BE795C5065110E59264AFCB5665442F07E14B39D591F3D56838C98C78F8A04CC1A2D1011B2D32323489CF31581E03457BD1876F6B2295F44A103F0C4ED3F939FE16C52DE113E7AC8F4C955FD88B180D8CCDFC605C13CB6657FB9E4AF7CC702B65A13B9C121536094292BDE5A7A752CEC8A2761B2CBC20E882F8B651DF73B23C4B23C3C8309A50A0AB8A7F2B43548A143C40A597D63946EFE4C9A24CAD0DC0B98C6A9129D6B2C2C18D4FA4837CE72084C514DAF3789FEC2A5098BFD2F1A9E056C0A20A03E62685E3FC6AAAB3AD3DC20FF4AC686ADAAF9D1B2FBA94B43D55984A5364B3F7B5ADE02241214AA5A663F11903E7550FD4688EE775DD2ABE3F3E5557C554567AF0405EBC8FFDD9164359FC38F5", + "2D13797FF507986C80E5F2B7CA112C219A73BF71C099943770668F7780A052319466C2296BF67FB71C65EE31C24027A00D3527F3B03D407CA04E43AE2E030A6009BA7B851332B4C5345B3964A8A6390395AB800B2C87AB4C852C099B950BC5324DF13230D698BBB37CD53738EB3447EBBA759C7A0FBDA746D348B0DC985BD9D7BD44482F9AE32D0F60060BE6A630BB51E32C575FC72ED3B2A1DDE00E2321961FEC50F4583B68D246AD1B91128A765F6C7BF93CA43CDB2421416C0C711334E23F32D119DDD7374718400ED8CB283B36115AAB9CD83288A817A6697C3143397C5990E4C8880806230B9361884C539A4466AE241002F7854914BD48B2A9B468238D1242EF4758708400DDD4A8FDB341DD87C7D4225E205AC88D47BED993796B239467C6A6BE986967A913AC3933CA1998371CB244711B90DA638E797E78A95CC0D230C39A1CD6282A9BAC68FE2514AE7833B412B034666538682765C424D9AB1F69578DDDF030D3734A620A4D22F24AD10692D5A08665688905639276D3C9263BBF74587816A188249010560540831AA1F438CFB156B701713EAB1C48F01148D5147A13318317A21AABA515893BA84A453F215A6C2B2C7AF219091DF5A376F8AD57825EF09896F414AA577524A0087086915E206AABB25C0DD5669444E6A1D1FBAE5CD5A490B0283D6B77DB658D54649BFB499D78B209DFEB815BEAC20B543D3F386675F253EC296634CC321983338B109BBA7B0326F766E9C90DD1C0A1916BB2D73664EDB1C6A04195A31BAC0302CB8AC9A2DBD725C579CBFB6A9344C4673380599035513586087307692EE79689D3C14A4903197B041AE98FE4643F86CC3B02D32C03231CBBA2317C16626C090FF0219FD7A1B32B5A0C6CF06CCB3341751A29E4994C9154303FA48789D8B12B773425EACAF84004BCB19B468127B492136FDB39791465090B5FBB36CFB42409CF785A5642047DBA012CE89848784A3011B68854299E2171FDD3A53B8B7C2BF3936057BED0F2067E316AD7F925FE3958C026CABF45AD10263DB78387E7C6C6CE7477FC0C95034ABA4531BE217091265CB2CDDAB742F29D21409F429C65B941AC60A7BBDDD91CAC04BE307C75F323AF8D6C155975C7C12839CBA17D22697F672C7357318E53285B19489D79ECCCE667692B116FB222A7DF8843DBA8BCA7611597E6784A8CC73456A9D297AC6D54B942BA902EE20EE8D755256717435BAB9BA336945B0E71B5986D517F02034A9E90C90307B7FEB500472A212949B0F3C5CD22C7324966CE7A10C6EA05598F22BFDBAB8E427630D2002A815B0B9626053D46BFAA65A896169FDF8CB9B763857F6999C6A7343B8BAE4208C71C600F950208068CB57A747F69A3A2215CA23F327FB648B20FD9C53E116CE58C2F4BAAA67758308708A0E14B74A548A8883599BC07173735402229196C7A269F72CF42845B0883095A57212631127010AC9E2291122B4CF416250FD01563A46031028CFF5745B475365F776841868B0FBA99C763503F337D41668131288C0CF84BA5530622F8957A56533EA53ECAB66C19C2094CE340D05A88C010A325017D91AC216A038EEBCA1892802F009561C6168777DB13FB7BCC69248761AB64FA0A403259997B18A17F48A725FB8672C4BD35699DAA1412DE7C09C0165836583CCCC03A59005CE7C890540C4B9CF05D330AA645A4BB5038672F3619DCCB427A370F437C16491A15A0C60950F19AF7599A1E299E6C40C828A2492D4474C9CC50A67C558351A8D57B4EE27A990982ABD3F935D6F31797E5A3ADD69C4C76893B569F22945B42E1413365C141A81A62ABCEAD2542837C0F1018C266605A06590C7A96296E875139FC7939CA1DF6C07A6F8271539AB8EAE8C25FEA4C313A590BC04E25E954C648732330726BCC3FEDC39F46320D82C9B20F229D211137053BA72B05CB2FC897212B184839AF8324A189B9A855C0B232447668D899EC675075D35FF5DB53E9322C3F3281622A05A7996CCB52159255AE012886B982A1E9A03CB1C3A0199A32001D75304068560162295C8AA8574ACC363D806356A9D388283CBD0D700C36DAB8B55874CDA60608FB90EF4609410459A5319A4F33AD7179329F178A6870BCD6084CD8B213A06C88934952FF75916987A738A3574C60451D70AF60C855D8F78C7E680157320938658F6A421F1B590C7BE87429B95F0B5A5178B25E3F2B61E9268D41486C05402423D12D529B2C8AD109ECC10D48E6841AAC7C2F0B22700985E21A4DEF6771F70AB01919562203925B16802824877142B93517733FE5922BE28638B728F6CBBF21D079A2A61BF1AC7995272031E076EAB6B68B12BEC782CC3C967FBC956C0F4C9345967D59C17E55C8926F342BC6067FAB55781ECA4D47016258C0B6A3A39C5EA98FB9F46745D52AB103ACF7D45D6488B91F872BBB313DF76247D297AEB8F87EE1C63A2BAB82EAC59F4F80CD9E1B845853AB0148A4F12A09FC9822180436BF7033C637CD17962B19472FAA98957B226C3A337A0489CBE3B61E2BB92DD0A390D54C5D56893529C75F956A415D3441F696B8423187C6B1C6A31C2C42F85003900540A21C00546B4AD75F1C001BC56443AE87A87B1993F5D18B4E1211100206A3665ED3868A510BBC70C6353DF89BF8B933D9762D499BA61257BF15D653EEF42CD737BAE25C03986644F9C97968CBA2BA7A8725172C78F15AFB659221115169EC08D0557C7AA996551061271747144C281C94181BA2177803BA6B671A13E406ACF5B474A0CA96D18A96997CEEE6082C218DB27C94FF4C55B31C2CD0BC4438AB719D1B1C6EF46E69298798986EDED0C83292A70CA0B061AA86B625C3803B6389021238457A9FE327957C63D7E11727D7954203C720244AA5D80F6C303DE49B73D71348DACB700B7A4BE795C5065110E59264AFCB5665442F07E14B39D591F3D56838C98C78F8A04CC1A2D1011B2D32323489CF31581E03457BD1876F6B2295F44A103F0C4ED3F939FE16C52DE113E7AC8F4C955FD88B180D8CCDFC605C13CB6657FB9E4AF7CC702B65A13B9C121536094292BDE5A7A752CEC8A2761B2CBC20E882F8B651DF73B23C4B23C3C8309A50A0AB8A7F2B43548A143C40A597D63946EFE4C9A24CAD0DC0B98C6A9129D6B2C2C18D4FA4837CE72084C514DAF3789FEC2A5098BFD2F1A9E056C0A20A03E62685E3FC6AAAB3AD3DC20FF4AC686ADAAF9D1B2FBA94B43D55984A5364B3F7B5ADE02241214AA5A663F11903E7550FD4688EE775DD2ABE3F3E5557C554567AF0405EBC8FFDD9164359FC38F5A5F2297286F62DF6AFAD2C416C876B55C9D1129505273AF92BEECEE3D1FB23F58FDF6905B494AC4D33DE50E94C0F09707654643DFBE1A36E7AAE5B9E4131CD91", + "74AA5FF2D034322EBF625A73E2A0C35F38AB9C3390FDDD656309E2AE19C316AAF13F104D294B8543F24D970F122A5099FCBE0BAAC8B421779FF1CA23CC59DBE8363AAD8B73EF10EA8DDFFEA58FDD12A4D474F33447AAAC13736D34B06E4E99BB8F1C17A0F5F50D4C64007431E781A8055861AFD2CB9A390B51FC051B45B5F23389E52F7AD85756A75F0BF8421B51DE2FDD7468DDD249B0A90EE52F058FBCE99C033398C9BCB36FAC742DA0F74DE679765FF92B8F40FCA320689C3BA451252C95902EF3BA37926B2F4D12D300A5A6E49273DADB281B8CFF493B809591A60C9AB16EE406D23E5F296A7028223531EFDA923BB6CF1585D8B17EB2B73DCFAC84E282B8E00B0CEAD38679A0D7AD977427C3C7DACEEBE5B792DB0FB8295151805D2B805A53101B0CD61DA00D80E49A48792628FA1D52432CEFEF7ECB4C1AEF36BFF4220E3CCA58EC02894EF35736BBB76A73171147459DC24DCBC7F49617004737BFDD845F59EDDCE74568ED0B60BA3CFC2BF7A4FDA2C850CC6D5ACF820A9639103F33022F37AC065DA563321A5B6536B4F215C00ABEC431B5B8DE23B17709D4DFA4CB57B7790E0807D81E613921249D30477402ED3D60D35692D12EFFCD9BA96718831810AB53DD189F4C5520FE9038C7C0B5A3FC3C324AC888A189228C468C2238B722581C07B427E8799D604FE997993B6A85044B1F2BB7EA6D3B75066D07E642D108004F2E17171E4D3EAA09BAD812093B76FC8823BF1C70D0612A302D5CE25ADCFDA914DB31A10172F47FC9BCCB4F71C85DC6E15C253991A1DE91BC7286881D87BF5035DD92953B6E1E91BE2E8DD5DD495FFA6094F40BA948865457AA9E2BA36F066F8B55CB5CEDF0B6AC0D24E84DA2557D9E16D791E199F534FAAC1BACAC74E86896569EFB00CEDC3579B32C31DE1561DF54398989D7CE9956861EC70E931E5A2882B90118DD0A30A1B22A1AC08430A07277840307E7D2FA9FA9E5A617A9A13A225A0878121D1AC53C85364CC21F65EF8DB5D2E3D3280763454A91AD53C79A276BE18D86C220E15CAABF56CF05C059DF4B9120807A82934AADBFC74252585BC0A60E7D5F3A2A73EA22357ACF1B87B0208A7D989E76AA4B646CA68626768EC47C04F21AAE8B01BD5D389B8957DD870363D45C542AE316E46A02650DF060672D32A2AEF67A7455090F47ACB37F2D495D9252E1196D8905DA59A75100383F8C54F177B52F0AED711486F58D4F6F4D3D9F108467A68A7344DDF55EDB8F36C19B1CBCBA01BE3BFF34ED738F431B2C053396D82C56F5062524C089F2FEF5F6F0DF9BF3323D471201676A1FAF7A600C10DE3A8CA921F563B1B41C705EA441B677DF384EDFA1BBE9BB0A6B877624349511F2A107AB8EBD7A17D15D78B8543ECF48CCF386A341C9D3B13244D34EE93371227CCC9BB8F206C98269840660288BA4F6803D150EA0BD364747BD939E2B0F96784C12D48EF667F48F21B6AF33FF7320694E618A6D240048B43E266475617AB4EFC037B27FECB24D160C1D66FE0F9276A9780BF3", + "A0C2CB4A476C1F55562C7BBB80B88CC98D48E9159A110926660F7CB053FCFE08" + ); + yield return new + ( + MLKemAlgorithm.MLKem1024, + "9D44513CA81A19B9619485AF92642AC01785C277AD4DB73FE96921BF98AE77A43CBB8B576439CF73317795C7130E76851B0670C12B2BA2555CF8F0C541010C438507913609579368BD922E506869627316D3655F20A62B4C8A7BA33A21DF71A964A9225BB81FA84ABFF9B81FB26A64BD65C4EEA5C955B33D2077A3EC9BC99B6A6F9339BB0926856111910701CCC6EB7502193397AA5C3E773FC453991B444001F474CB18AC7957696A643911555DFACBB03CF9050FE86F7E30181065AA486021D4C36B4C12CF34241852FC6CD322531107B038E46760C59E112149BE905C1915B22B396F814C83A3A1A17BA9B337B0C4D3213C79400037FA80BB3143914B56A8E45DE6348325004D5BDAA461DBA04FAC2E57890F1F256D9BE984E13B3200035552ACC6FB319E756948D7363510D9813561CEF17599BBE584CBA99E3D6564D53C30482A148346BBCD1BA4F56017AADC1A6DABC127F23CB595405B930D41185E56F51418A895294C21470097DB0B1E826619D65C0DFC2123428C88EEA040F4346A83F46173D45279F239D55600F1EB105A86A1FFB61738D6283A03B889E7238A31530FF869DE598235ACCB3E50B80FE59BDB2641F2855C38C643571A629C0B2B87CBABE6C6B0BDD7B2BF415A0B90266564B183E362CD8474EDF93C2D780F69973765554B6D50C7AAF23F4B79BFD8F8973B827C9A92625779BE873A92A9D9361EE20C31559DEC154E8BB5592B85C8A1F64CC13B7058486947C1929E3C6C7AA375E6720C41E03FA43045B549A05B97027178BF7CA62EAB0B123CB232A3E4CBA2F4BB66980977A78A7202A25527325C4B5682F79B3614680D9B9370C888301B133FC7BC74441A8FA44979C311C26182E01674CAA2372C681D53A019F7E1213115257E4C9FBC90478EC760786B6770693F5EE149AE60CC7835C0844177D8C04E54096A40491F8F6352A231C8E3348F4A02558503C18E2336C982226937AF63A15693025D85422D695737D649A04BAA617B6524FF8853FD664966302E29FAC6162848503908FC0BCEAB9710A806B81536CC78A332EEA70F04F27C6DF9645EB516B7D97B8F84C8E8C2C5ED87C0678795884A893866B853A9AC0B301C0320AE07C54C9D06709E66A90D69724F4192C6859DEA8054BA294FADCA6DB075233CF8AA159144A48C0D8CF4CD51A78A9D23A805E632BFAA587D66A7DE052829FB9FC23C6F66D6572020C60166A220C5432C24886F8553BB7214676AB135535D0CF711845C0F654774F591144D498CB93013E5676146361071E047452CB31AC8CB1F19B35A009CD12C0B0A7A84B6D983C388890E64408FE68F950584A917695B3304B580B3EBE45DF29B2685B02695356CDCA01869F4BE00A9930D384C5A7C8EA17B7033382DC0DCC806DBAEE26222B94C0A775C0220BA3835659F002C09CA37A8B5870B7D2521271B643496394157C621D44276EA0CBDEB0A01C6094B0C6183C92A9638BF1694CEECF66A23CC7C6D0664D4D09B58F39E6CD1CE4D125B08C66FDF0514A3534F026CC4C2517F9C137288232B08BBAADC635EA6024A8C4667E8DBC0B56556DC565D5C08C6963A33959B67F5A32A851B621A8B31B8704C97D0499FFCB6DA2A54DAB35E2CA31C722856061B3DEEBC7D6E5BBB64A40FA5CA1AEBB928BC3437DFA449486225941948A7228D56D7A60AE535A30A7A04925733F29A3E242F99876E7981502FC00258E67A1367778539C1E8529FFB707E13C1446099C6E681380F9A2D2F90BCA121009B822C1854B185A51B0BF61BA0B56C6FA002A5B675DC0A0752451F5C92CCDE666569FBCC683379FE6A850440346A3112888548D47B0468D7481A840946E53C0293C7696BBE88A914506A49CAEB3E233BBF00CC94AC74B70BA2A57D4A032BE3C1724382FFAA002DD7C9F025189CC385C1A24C10AC716376C98B5356AE9AAF75FC931E342F5986A146E3855F6873CC8BA3CB86BAD732241C313AD17883E86C5E2F5486C092BCB4F718B83213C95272D134A2A745A4D6309C266431980C8A0F86CB0CF03247FCC25E2072D5574009D4B61DE9608B29B44488942CB27FF3749A9480408E62AA47A0425D74CDD276B26495B0956BC398AABCD1FA51D5C342C5C13677D46BBFA994FE633F2BEC53C0B6BC50090ECA590CE5F6B30A9436A741AD68C7A9966BC9E7E3D0A64ADBADDC6AB2F71F57AE0AB344F614619AA6DAAAC767", + "F1B84483E2A3740C62F7B50CE3588848FCC3DD4851D8866250DB6EB10352C7AB582F537F25C0205CE97AF7D5A0BEA7B2230C37D496A47BE92C3657C924497C3DF90BC3B547C3A129C16532F3584620D71F99253EB0275682B75007B5A1387268615708C210B9C8F370CE8304377A535B8CCC0E550DF7521F18536A0AB4AADA863DFC81BC1044B37135B42584A8F7121DDA4036EC869566D551E3EBCA35902372580CE55A3B58934D8E445980453FCD1B9A1C85B73748A98FA837CF677C23268AB2EA42BB642198CC4631753104E9121E3832D34C7CEAB049F7D22F425C093FB6AA070ABB49781EBE1BBD55F663957341E432818169CFA8515C9F044766C397C191C129355B244730339B8E6404CC63B71A1E93349DDB5C2F995F61EB2508B96D51522A3532C14DCB095AA92F2E16404F1B2328006AE9EC5FB9627975B2C764432382A22076F701BD9A5E281909E3F8393DC3671CF26574B412A19B04D8372C5D1550961B38C6DA7B4B0538C978A4D3D8B61007193B1CC8D773777042A46BF496A1895584091B77A498D164BA4BD1C9B6D49A262AACA8CC03136389D480CA458348F9B2B67840180F014892477D1589C89D42B0097A72BFD9C215808B7317922AC360A8D5B1E3689535C45246948501DA8418D0464708CF8FE7A18566920E086EF879BFC154277E9BCE9B7906EFF0B3B7C33CCC09424C41A487B624A692805C5003B7E98058FB2C30D762981CC164D337C8B830552724AAE7B850625EF5556707520FEB633868270E0B40245FD07239B70C8FF00E9236409832551D252AFBB860739BB6F2427B42F0A08FC264EAD743F1E16E592BBB32B99308FC969980B8C4C685FCFC96E5B1BAB05A343075B327D658753B2065693FAC5258D6C149260183B7AA2F100B0564A6553836373A082D1E2843F140984B37ABC75A36A65B0162F958275ABA3A4119641709DEA1028FA620C322BEB210A68634CF93968C5B80C6AAB3A137A14440FB7E65C570CD366404853D9EDA9FD513A20332010298AC6AF9C85049B3AE4368450B02C598105EFA6B7A65820C659FE220B7B831A62DE7002719A7FCD18309AA154B2C3B28932B85822062B16189862F9E89CBF48C6FF612165F529424E34A72728DB92564F3A4135D3B35A4EB5D113890BAD49CFD4678600927C81586558818FD72CD048BB5A6682241081BE2B8B6E9077DF172363D32AA81CCCF5F4BCF2DF0324A2AAB062ABC2B2ACF591C59B56BBD10238D49202803D31A8C33B39DF9A2BD35CD6F8AB6CFAB65717B327148AAE2F598A6851FEE9A642115B7CA392DB1B273BA6A0D6EF2CFA010259B95957195BE2F93A3FAA68C703C7192AA6E7466BD766C620323662943038E349028208D1ACC70BC396D75D4526DC53CC50C4B546CA24969163E06B6246A542C1C776414058B458494F804510817F7DB8F55F9B32E85352FF6A8864359DD39621426711733A929391248D31A7110C80819795601CA211B87AE4323593A5987C89B24C55039DCA23B28A477416974699D27D6219F943937B9C44C472041BB9729624C0A2358CF908505F8C270F6CA12DCCB15A63E8BF88F4C431B5137BA0F6C90BF209832633B0CBA8BABC7617427479701287C35AFC06163B0429B155B91D414CA16D23FFCBB17FD1C3DCDA8262FC3798B1B1B0843CDAAB6C2609422419C54AD94783EEC42D06BB60F844B58F30427908156A660CC5AC63A5B0B2D8BC496BCC1AFB0CE4555C15956B134565F6C5B3386C57013074400E268CEC74A79C08112F734E316C969471389E94EBFDC14416C106CCCC8927B97DA76086B2C5FD76891A62C5521137DA3C30614361984058214B3507EE932682301F45CA20ED97BB607150AF70AD5DCAB4B5B0C3528969AC029C40CB484788A4568A654C32D4224A22E6A5D6F539F0B94AFDDA10BAC1563807686C48C07FDC622C9F153FAEBB85528C53C0ABA383BA51DB5925670BCCDB3C5B5D2C7750A2E9A83B51D1886C70534C8465E9086AB7851541AA4A6B0E96304CAB8B452C355F52034E2481F426F85B03899DA6B0546BA427AC751C84461952A9DC0A93A706B174733D7081CE724AE7CF04F08CA5B92A6CF0495A10DF2B682FB16806B9CDB6157D6FCA8C8A5A8E8970AA96434B27BBB77D41B1C4821EA6A8F870CBB7422499D44513CA81A19B9619485AF92642AC01785C277AD4DB73FE96921BF98AE77A43CBB8B576439CF73317795C7130E76851B0670C12B2BA2555CF8F0C541010C438507913609579368BD922E506869627316D3655F20A62B4C8A7BA33A21DF71A964A9225BB81FA84ABFF9B81FB26A64BD65C4EEA5C955B33D2077A3EC9BC99B6A6F9339BB0926856111910701CCC6EB7502193397AA5C3E773FC453991B444001F474CB18AC7957696A643911555DFACBB03CF9050FE86F7E30181065AA486021D4C36B4C12CF34241852FC6CD322531107B038E46760C59E112149BE905C1915B22B396F814C83A3A1A17BA9B337B0C4D3213C79400037FA80BB3143914B56A8E45DE6348325004D5BDAA461DBA04FAC2E57890F1F256D9BE984E13B3200035552ACC6FB319E756948D7363510D9813561CEF17599BBE584CBA99E3D6564D53C30482A148346BBCD1BA4F56017AADC1A6DABC127F23CB595405B930D41185E56F51418A895294C21470097DB0B1E826619D65C0DFC2123428C88EEA040F4346A83F46173D45279F239D55600F1EB105A86A1FFB61738D6283A03B889E7238A31530FF869DE598235ACCB3E50B80FE59BDB2641F2855C38C643571A629C0B2B87CBABE6C6B0BDD7B2BF415A0B90266564B183E362CD8474EDF93C2D780F69973765554B6D50C7AAF23F4B79BFD8F8973B827C9A92625779BE873A92A9D9361EE20C31559DEC154E8BB5592B85C8A1F64CC13B7058486947C1929E3C6C7AA375E6720C41E03FA43045B549A05B97027178BF7CA62EAB0B123CB232A3E4CBA2F4BB66980977A78A7202A25527325C4B5682F79B3614680D9B9370C888301B133FC7BC74441A8FA44979C311C26182E01674CAA2372C681D53A019F7E1213115257E4C9FBC90478EC760786B6770693F5EE149AE60CC7835C0844177D8C04E54096A40491F8F6352A231C8E3348F4A02558503C18E2336C982226937AF63A15693025D85422D695737D649A04BAA617B6524FF8853FD664966302E29FAC6162848503908FC0BCEAB9710A806B81536CC78A332EEA70F04F27C6DF9645EB516B7D97B8F84C8E8C2C5ED87C0678795884A893866B853A9AC0B301C0320AE07C54C9D06709E66A90D69724F4192C6859DEA8054BA294FADCA6DB075233CF8AA159144A48C0D8CF4CD51A78A9D23A805E632BFAA587D66A7DE052829FB9FC23C6F66D6572020C60166A220C5432C24886F8553BB7214676AB135535D0CF711845C0F654774F591144D498CB93013E5676146361071E047452CB31AC8CB1F19B35A009CD12C0B0A7A84B6D983C388890E64408FE68F950584A917695B3304B580B3EBE45DF29B2685B02695356CDCA01869F4BE00A9930D384C5A7C8EA17B7033382DC0DCC806DBAEE26222B94C0A775C0220BA3835659F002C09CA37A8B5870B7D2521271B643496394157C621D44276EA0CBDEB0A01C6094B0C6183C92A9638BF1694CEECF66A23CC7C6D0664D4D09B58F39E6CD1CE4D125B08C66FDF0514A3534F026CC4C2517F9C137288232B08BBAADC635EA6024A8C4667E8DBC0B56556DC565D5C08C6963A33959B67F5A32A851B621A8B31B8704C97D0499FFCB6DA2A54DAB35E2CA31C722856061B3DEEBC7D6E5BBB64A40FA5CA1AEBB928BC3437DFA449486225941948A7228D56D7A60AE535A30A7A04925733F29A3E242F99876E7981502FC00258E67A1367778539C1E8529FFB707E13C1446099C6E681380F9A2D2F90BCA121009B822C1854B185A51B0BF61BA0B56C6FA002A5B675DC0A0752451F5C92CCDE666569FBCC683379FE6A850440346A3112888548D47B0468D7481A840946E53C0293C7696BBE88A914506A49CAEB3E233BBF00CC94AC74B70BA2A57D4A032BE3C1724382FFAA002DD7C9F025189CC385C1A24C10AC716376C98B5356AE9AAF75FC931E342F5986A146E3855F6873CC8BA3CB86BAD732241C313AD17883E86C5E2F5486C092BCB4F718B83213C95272D134A2A745A4D6309C266431980C8A0F86CB0CF03247FCC25E2072D5574009D4B61DE9608B29B44488942CB27FF3749A9480408E62AA47A0425D74CDD276B26495B0956BC398AABCD1FA51D5C342C5C13677D46BBFA994FE633F2BEC53C0B6BC50090ECA590CE5F6B30A9436A741AD68C7A9966BC9E7E3D0A64ADBADDC6AB2F71F57AE0AB344F614619AA6DAAAC76772B1D32CDE082B6E240351358470809889513B4C05C4611B6C02F4E0B4AF9C2890699250EAEF4F0DD68C72720BEB1D19804203EBAE8B8903D98F25903A764877", + "BF5EF354B5EE7D74188232802D1B421F0C17012ECF2364E4CB996067AB6270BF034E5FB475BD2EB17C1708E4AD606FF23D38D27C1F4E524CC9767087F7F042F09B1C080B055F27CF879779D129823E4A491DE0F9AF496F04158DE90637547262D3086778AB268665CDEBFCEB85F3C5E02ED837AB43DDD97B456921AE2E03C88CCDAE7757A4773B1A207CC0B11B170F19FD70F25350849CB6C39AD12DC69352B4C4A6A9619CFD41EBCEC4E26B3B0685EDEC45D87879940C4C6E5C43FAD20C65FFF64F676847C4A63E7AE6144404332220CCF51B84C26E726DE976A2CC3AE143BC99B657B5F16290B37E43F8680B6BAED4F033FDF189376882DFF74864E55542CAEECB0B55B3FE2BE91EE73A20F74D5AB984F868CFBBA63EA7F6086B19D624278553378C58E3394FBD1FDB7EB86D919FD99D1B79B59BBB4E5AD0EDF7474DB392F2DAEDC3910D02E636775E313E7D14014027CFA561B66D0B249B6574A35CA45F2CF9AA63C2C71B970BAA3DBC0E0AF1C429FBD8D6E91D67CCA4EF9755522CD0FD49216F8D2BEFC9E37E7066315027BE0DC35460B4DBDC64C07EAA19C5A135FE9A0CEE287CCE67A66BC8E541936477A71157180EA185165E41230DDD35408448D9EE281287D6C03A9FFF128E7B3EF71512CDFF126109392FC44977BCEEDBB12C213E4A40F37AA7559A85945E4A14F6715CAE676F07B5237EE46968AD41A6B0AB4B2A0E558688326B558E6EA8FC925080DB42629CFA1F2BC13BE050476D9F0B2614E9EB0485CBE16C678ABAEC1ECBBC82B506A183EE8B66AE938A57A36EC1023D3981A38AB7E86FB267F722479751B0D01092C3D4F267419865225B1E0FCD50DB4E92172D5BA2DFA8D27F7E7F3971C116581FFDE1EB7C97AF66448ED55101A774393159BD058BE12640AC403AC8F62289938F332206AD1C82D8E0C969D7EBD0DDDE9B6A45E3B5B1CF2A6EBA80F91EF87E347B8EF4758EE8654566BA7DB32CAA8D79C914D291EBFAF7E9C6ABA393972F09A5C8821D435EECCEE94EFB9341561E367A15F5ECF2E4758A0D3558D122907FBF1BD0CC21419C9E6D1157F2A41E3CEB5C9C5089666A81D45D28CC30053CB05EF23235C78B121C5CCBE5E72056A792721FE1427A0CAE8891FC8AD94F80A4BCD1AA1287225532C6EAD21C8332AF19F1333095901F83EAEC30BEFB9CD35F2F056452F682211F4AA7E4FD886AB72A52DA710B4B19ADD0722B8CA090C349CC20C04020AD8284D24E67038AEA537E2F42009B24474EC61223D312AC332C189A696E8047EDD788EF78C3A999BD2724F56FA0BFF16A5F4899DC401C6C55573B954DE01F6C9928E2B1504DB33822623B2CCA44D2178AED441F1F420952FE61F1161EEE907F318E1C693BED9496DCAEE654151CA576EDBA2FBDC12714FC37AA2A3EE7BB167DE1ADE78F205C9E92B4E58A2D8A3D7C8788A167AB1B0EEE549C292BFB25B847B0BB7506A69C32DE245EF8D95E625E89A5C20A3D9823C0C021F1B703F2ABD31B0ABB5912802BE89E530A021A83F65EE94A17B091841661A3B63DD2812AA85A52E7A87B497FA61AE16BE69DD68EF016FB19904E8728B8647B4CA88ED38B90870A1BA32A2014C1887BF9390196B504F950C983546C4A692BF5022BF54664328B4C82D0085C8A399C96D13780F4FF9FC11EAC78F2C689CCFAF4483195ACEE717BDEA3EC75021E1691F53878EA9CCDF1D68134C4D8AEADB1D3DFD241424B2EF0636A35173DE770D0556FDBD7852B74A2D9F0D1D8DB59B4A634B1970E3A4037794A2151970B045AAA667F50549AAF71411792D613B1424AEB3748CCB1C844109D0FE6BC9E10E50FDBEA5FEA833BDAFE4E9D9910E366BA08792ACD7B2FB525C5987E16F1A7651B591C1503C7CE66D6D1A230B90C82CD7B503C55BA9D6951FB3C9C626521EBCDAA0584A05589889D018644E6ECCCEF120BED7079C2E1C66C0975B0BA01C29C0F7FDA9E3141449A1B6548A6B7A6FAD868C0A45E7766FC2D637A2A8A3AE68EC7FF3917C512B51EE5F9D54372B42440892F3DA9E4CD713AEA0311EEF7A5CFD8E441DAC5781827D9FC2C86E09D5C680C43B997CFB2D38D2A2019DBFBC144D2C442BDDC12DEE0C6DF9DC101E6BF0EADBAF2A89CCC0FCE10ECE108ABFC2BA288E64D130B2D72642F0456EA24C8B2BA88AD24E5D71778DDF85F8C125BF4710C0D333E4F7D547CFD4C6282BBF9A81BA8707804EA", + "74E9A374CFD12E92610591E05E80F256FA9BC85146F678C0FD538ACBBB765A6B" + ); + yield return new + ( + MLKemAlgorithm.MLKem1024, + "5CF432212464C32C44A8CA8FA6F6620899B08E968B2F047B42B00527901974337D3613C1BC278EE8D5C254B4898E1088D4A8C09EE175969407C01B11C5F8239C4A0455DA5DD6876C18160944054F69545A5340C5E2EC8A378B1824D313D4001F20FBA7B878AC5F490E0EB65C12D0ACFF68C9F9E54170F4137A4C206834BFEF81651C61BF3A6736B981A222994D3571B1B802B5D759847E915A9BB0B1CA894E055B1DB0FC5D7EE39C5695C10A3112D4E2A0364036C1824C7F32627E81176E659AA1B6CA4EA3CD6591CB7E86CDCB57A6440B6D92B08A628C378408ABF7B93CEC59AA19EB648B39170CA87AF41389ECACBA26919DBD3C4870360A72A398DC7CBDA62C26AE6A0419E5229DA7C77C725FFE9AAFA9EB0E5BEC8B1CCA02FE97379DB20143E21E1AA8BBB55B724BB668C10932BA9C58A24536CA9CAC675350C7F72157B0AF497BA4B16425F52069EEE144FA96A40DE99A1FE10D95F71102FAADF1A8A0FE8038B5A49C04C952C97C65685965E18A0BA8B805AE2839F61278B76265082329F6CA4040242A760B6CFD683D52D6BD4E1156BCD181D4C16FDF9C75426A8000B6952E2A023D3A59844B72F3D9BEEA35BE4F70988871C6079A2F49474599C9A0BBA36B8CC41865363B42554D9722B9CF7A5BCC1812889BCEDB1B4DED8B48BB42695D83BE31A543367819EC75851E1B920BA69AABF57007CAB1426C56EDB6B6F6832C95C0834581BF6240674D336D2437B820E84040BAA93D2056C1C3B2F9A0A6536C19F43A1D0904C188421805451BB91C908F159B1D308071D3886287C2CA56263C60A43F67916A3A79B2FA0B1BF897E941514E78968276508F3135D8A9B8E0D781FD41C05EDA9F2C4A9B4FD33B1C80BB690C59BCCC8CED95C1DCE72136125128507F30A465AE10AFE44CB764697B8DC1AD2CBA07C73BB888C9A559407A3D0636A4134A3E162853493C25770D10847A72956FE3CC01778049B46142AF4B4AD1D900B44A149323190500899D2801AA5C031A0C378F5CA3A778C8B7B688EEA26CD720CD8858A07DA46C176C08278B7C5D47AA6AA92753C75BDFF72E88708E6627BEC0335331D38604E84EC712B0D3EC8714E56FFA8807F40B8CE6C3723369883EDB462AD9BC972206A16C78DAF8C1428344E9C76B161A818BF8835A0043621B3841F80CA3F02970F7882B715EFF117B80E125ABFB406BD75027F9AD34EC7E7B629C2D834C90225020017CA511C8E83CAB0F98C739EB030E172A67586D90A5827E063B9C7B0705BB61F5A6067D102776F18950C3C2540198D916B7D64C803EEC3701799DA2C176AFF38C26004F3BC18144A3501D80B580C1442AFCAB6A458C1BB49E5A5728EB2818B6EC539F5C931F9743EB34B889401D19D220CF7822DB6906006B59A5CC90992691A2071631A96B6D8617F7E863C44A610E72A34CAB05D68281D07088D23580F0A87C870684D74C66D1827BA2702024098377AB359F10CF21B7C5EA9A77ECC121B9D81E52B4CFB315CE0076757EBA100F87A3CA1B28785C46B2B2856160213B09B3B0844055515085F721EE47356E31599D0071214C8B1EA44374890838D1C6636383CD9376D131CE1139277911B221A5CFA182ABE535AFF8995F573B55CA3C08CAFBBEEBB92EC280BC351735A5891997972104993F53321E70E571E86250CCF96010FB59FED89755317A0BAA5F5AD1A6CACAC5CA4612F2B27E94D6B61DCB138A661B28B03091C173BF96CFBBE00CC94223328B55F0B848E27497BAECC6A588C24EB34BFA771C94B4C3B6F87A54458941691C6945470AA68552B77DE5245CDEDC8A457805CEA024034C5731C296E0A468BCBA19D0DC7EC3A38615B10E1D7CB9B61315786A2AD737B384E511AB0CB300976324287063A76B589B88A686A276CA770AC9B79A0B0420692AF8D28AFE392135A62ED20C953DBA3EA0B1B740715DB8084B16661CF9F497BC8BC509E9A9BF5713769CC309090ABD3BCD49E69A09B6BD01536883B5ABF87622A93566B51B1E0C8A0A191A0F90EA5995852BF0EB8B3F15BBAAF55B82D900A74507D167CED79B5D51B5A7791055AE835D79C1B0FCCC0B213664BBF35D9B604356A23E89F9510AE2B8EF6BA3FA52387AC92019A773C4F26DB9F44801F00A2BDA3C14B2953486A7E5605E1B523F894510FA8BB85A080E589A4538F3E0C08FF714113962C5A6FC29172509B3C1AEC2FA41707439", + "630859B0E9292AF46619B7312DE45D6D4B01D4A4BF075372B8A345E1CCC66F3257FD3A5B47EA046A168211C807672C13BA4A48AE742DEFB760CC7446F086C0A8B439641A24EAC5CAF3A730CD3215BDE8B419CA04FAABC3FF0CCB8BDCC8AF1495886B6D33B01D25B032F7C3282AA9259E5178D5841106797A5D559882CAAA17EB695C397BBDD297A5E24A9E00532D355286C09197FC0D186666C5D5360E42B1DB865B1BA950B7D1C2CE46B64AC43D89404CCEB3CEE397175237B618D4112917535F250F2AF42E1A05282CB7CE65C73117F934E1B661CEE4763C375820F09F87916615865E30E146298B525B730B1D89AF469509A0F06FCBA5CED2405DC210AA39FC55251A80A8A0037389CA7DCA5D9A10B777B6919B6C1E805588E3F20849E7B2033C5B781B0545A84E842961041891F91A5E5D4C211B86B8ECF91DE0AB42919B1A5B2245EDD54689AA169E61152DC94FD9C1B80E1602F3E69F9BC38455C93FA2757E14A6369E942E8EC9173C9BC9168B83233902EDB01FAAA66CABB796793C53DCE32C1F81C329215EE9002D8D09494C8301218A379E1B3EA221BF2C36A927E4BDE0F27CC72735FC4B3E7C181F07270A8903460C88B5BE499B5763B79BCA1FC964B75ACA1F2649AB34771D90855C03AB8262F99B7859651FC49AC5119AA48A8931E19035C011A2FA7EC4464DC35B8D7D3392EE0B710A98B3E565CEA3925FFC9202DEC07042A12C677126ADEB25EC34BB0343A1DC311D55F464263C0E32287EBD5A6735682ACA478DCC34B5BF119D153A2C26BC4A47E743B5721A0A1B3DEC00196A006DAD826849C1146D01B891F690D7F116187A966A689E4475B6724445ED17CF1FF4026C8B587B600FCCF148D47852C546A70BE6767855603C77258CB4BCFA1CA310D533171287C5166230C759430B5B1027B8F7C1BFD8051DCF29B090423C93E3301E39ABE8F3C145735D5B9A83E5DACA1E013BDFC51ED05A66DFC8CD32798C928627C98393A1DA003C797BCAC402D3F1C6AD5B8F56626D7954A7C587AD7C7223D622A58169B826456088AB50D4A48EF959124271479E6AC7D979675E222ACCB2BFB8748AA9416B0C67288BA75963196819BA8B20B116F79955AED72735C08BE4297F28ACC8DF25215765C17F9A775310699993610A490F2368A87E9019CB60370E1749721B409B398363FA49F0246C08948674E3670F32525A43C337EB9677760264A05626021C2DE7C180935D3532285905AB71F3B94A259DCAF6CBD62BA5F7129AED0270EE86483673693EF90B84AB39A3CC10FD322D7A989E527920526A94DC8CA7AFE677376625B41AAC4BC4027A316323C877C5F5811888925B81A76EBA5D496923012B37FE6C2827872B81E65339AC8BFC57AE68A3C900C026DDA6AEDB09A3CB98CC2A809A7218B190A5749C42AE4F353124809D78733DC52A89850159AB73415988320C7A093C01D03F4492293856A531A4F013950E30C7A548BFE0466987C339DBF08E9A0B4EDECA083C399F2E6971CF3AC647FB5EEF401759E6C292F038DD732847545A63E43E17579C818C3DE888895F3AC712DC6C767158BE311F24E44FCF91ADB2663BBB0B1ACE801495CC5ABCC208F0DA634046503C694646E9368E43CD98A02DA67B1138EA5FB5BAB0DDC87F85E0A2F7B7308AC26B72427BF7F07DE8B5C304A60B23AA50C2E05E68A9206C3859CA017034814242F49C91A734353C0C17D075E31412245C131CE863E654927337AC046B1BA83214336C32CA8BB179F671E010922080BF1C2891967017459788E4B69131651BCE03911AF8AEDD6570ABEB17727BA25C719E69CB226076780BE183FE705E1539480C147773E3C313C359C3B13EEED49139B27AA78736F41283005CB40375C2DBF28D2DB5A767F0814D661B7E483048E465EE012E877760CAD3A25BA95356C087E596540A603DB8BBB45CF05D0D6431E4B5646D045972FA81524B9476F07F03BBAB400150E4A840853B768B0C02B1D75EB4748E3248BCB7CC037EA70F882299EDD18470443D9FB7A479D83A239809C166B6E7BB61ABD1BDBBA7AEC9B2BC55320F17FB72BD842D52DC8315A8738875ADBC254E5AF369FE32CF8AB5CC45459D2F7433D3777312F17171E3B073F01E0D175935E7B870676D73C1015DA7A64D6333E6601A94902B5CF432212464C32C44A8CA8FA6F6620899B08E968B2F047B42B00527901974337D3613C1BC278EE8D5C254B4898E1088D4A8C09EE175969407C01B11C5F8239C4A0455DA5DD6876C18160944054F69545A5340C5E2EC8A378B1824D313D4001F20FBA7B878AC5F490E0EB65C12D0ACFF68C9F9E54170F4137A4C206834BFEF81651C61BF3A6736B981A222994D3571B1B802B5D759847E915A9BB0B1CA894E055B1DB0FC5D7EE39C5695C10A3112D4E2A0364036C1824C7F32627E81176E659AA1B6CA4EA3CD6591CB7E86CDCB57A6440B6D92B08A628C378408ABF7B93CEC59AA19EB648B39170CA87AF41389ECACBA26919DBD3C4870360A72A398DC7CBDA62C26AE6A0419E5229DA7C77C725FFE9AAFA9EB0E5BEC8B1CCA02FE97379DB20143E21E1AA8BBB55B724BB668C10932BA9C58A24536CA9CAC675350C7F72157B0AF497BA4B16425F52069EEE144FA96A40DE99A1FE10D95F71102FAADF1A8A0FE8038B5A49C04C952C97C65685965E18A0BA8B805AE2839F61278B76265082329F6CA4040242A760B6CFD683D52D6BD4E1156BCD181D4C16FDF9C75426A8000B6952E2A023D3A59844B72F3D9BEEA35BE4F70988871C6079A2F49474599C9A0BBA36B8CC41865363B42554D9722B9CF7A5BCC1812889BCEDB1B4DED8B48BB42695D83BE31A543367819EC75851E1B920BA69AABF57007CAB1426C56EDB6B6F6832C95C0834581BF6240674D336D2437B820E84040BAA93D2056C1C3B2F9A0A6536C19F43A1D0904C188421805451BB91C908F159B1D308071D3886287C2CA56263C60A43F67916A3A79B2FA0B1BF897E941514E78968276508F3135D8A9B8E0D781FD41C05EDA9F2C4A9B4FD33B1C80BB690C59BCCC8CED95C1DCE72136125128507F30A465AE10AFE44CB764697B8DC1AD2CBA07C73BB888C9A559407A3D0636A4134A3E162853493C25770D10847A72956FE3CC01778049B46142AF4B4AD1D900B44A149323190500899D2801AA5C031A0C378F5CA3A778C8B7B688EEA26CD720CD8858A07DA46C176C08278B7C5D47AA6AA92753C75BDFF72E88708E6627BEC0335331D38604E84EC712B0D3EC8714E56FFA8807F40B8CE6C3723369883EDB462AD9BC972206A16C78DAF8C1428344E9C76B161A818BF8835A0043621B3841F80CA3F02970F7882B715EFF117B80E125ABFB406BD75027F9AD34EC7E7B629C2D834C90225020017CA511C8E83CAB0F98C739EB030E172A67586D90A5827E063B9C7B0705BB61F5A6067D102776F18950C3C2540198D916B7D64C803EEC3701799DA2C176AFF38C26004F3BC18144A3501D80B580C1442AFCAB6A458C1BB49E5A5728EB2818B6EC539F5C931F9743EB34B889401D19D220CF7822DB6906006B59A5CC90992691A2071631A96B6D8617F7E863C44A610E72A34CAB05D68281D07088D23580F0A87C870684D74C66D1827BA2702024098377AB359F10CF21B7C5EA9A77ECC121B9D81E52B4CFB315CE0076757EBA100F87A3CA1B28785C46B2B2856160213B09B3B0844055515085F721EE47356E31599D0071214C8B1EA44374890838D1C6636383CD9376D131CE1139277911B221A5CFA182ABE535AFF8995F573B55CA3C08CAFBBEEBB92EC280BC351735A5891997972104993F53321E70E571E86250CCF96010FB59FED89755317A0BAA5F5AD1A6CACAC5CA4612F2B27E94D6B61DCB138A661B28B03091C173BF96CFBBE00CC94223328B55F0B848E27497BAECC6A588C24EB34BFA771C94B4C3B6F87A54458941691C6945470AA68552B77DE5245CDEDC8A457805CEA024034C5731C296E0A468BCBA19D0DC7EC3A38615B10E1D7CB9B61315786A2AD737B384E511AB0CB300976324287063A76B589B88A686A276CA770AC9B79A0B0420692AF8D28AFE392135A62ED20C953DBA3EA0B1B740715DB8084B16661CF9F497BC8BC509E9A9BF5713769CC309090ABD3BCD49E69A09B6BD01536883B5ABF87622A93566B51B1E0C8A0A191A0F90EA5995852BF0EB8B3F15BBAAF55B82D900A74507D167CED79B5D51B5A7791055AE835D79C1B0FCCC0B213664BBF35D9B604356A23E89F9510AE2B8EF6BA3FA52387AC92019A773C4F26DB9F44801F00A2BDA3C14B2953486A7E5605E1B523F894510FA8BB85A080E589A4538F3E0C08FF714113962C5A6FC29172509B3C1AEC2FA41707439B37161E8A5BD109953D75BD81E062D36D81EC8718B0FF11F835FD02EBB0E37D1AF05419B0CB3DE1B514404D1C0DB9017182CE71D7A0E69CB141A94174CC758C0", + "13E45134547251CF55515976985578ABA6CA97FC3FF6DEED8E15AD947117FE7D2F2DACD7E681BB899F5F39AADCA87326085F01FBDE655E7C8A3711C9EA5F6604A547D3D019416E46EBBF851BE3C2703A3241188104EC340BB548E5E37B65F2272C104802AB743C88908D299EE6B9F1DE6F8E0038CC9C4AA567341A4984A8F101E2C2B2795D29557D84D61FE9A8CA937C2123F02BC595BEDA11431C1A2A7D45EC5730638BACCF5FE8397F8F3893C729208138912B846803DEA9D70425F52F07CA7B0BC60B09EA741BC737E60B7C27833BB1C7F2A8D650A7E5ABC1A963350CA34C852134A650254389F04EBED26D33F0BFD24877DAB9FA7173B12FDD6B52CCFD5AC840FE04E2381781A626C814B58EE149FEC67A5D978222AECF323E60AD10077FFDAA62960326191D9513F5E44B22D318D51DECDC1598CFEC5CCE77EF12114ED335837A9D999CA572A392B735A1E10808801687F66B8ED5E10D5E0E7561A1CB07E411CB1D2EAA5A55A9DDD146B661564CAE0BDC4FB175E508C43F6A41E2FB31A38F6A6750AB9B92C69B19CE9741733B77B49DCA86CA6A899D39087F285003358D5C8ADD8A8A5987B8B0AACA4661DAC7301383D80B1EBD29098BEB447E0159F06D72A414F0E28410696D71C7D717967196A22160D9B36615240D75998B0F1177332EA3EB3EB6F9B533B939494716A935DFDCC862EC0A25DA2908831A8DAF5030CFDD0262D0CB5DECDB4B468A3A75401D7878B9714F4C4D0C07538FE7DA6CA3FE9AC5FC829787CAFE2833740A6204B85E951E6AF2D5DF448F125004D85A212900DABE0361336F6284A8E3196B06AC45BFF78A10759D33307C4F6861641A8A515B2A56892B4640B0FD5622637ADD9AF0BB1C3F742A7803D2634236C69431C0A41D99E64A8B454652F3FA507CE74233CA4F49DEFFE91A16A08AAECEC3EA8DAEFE6F0981D2B4158AC43E6E10A8EDA0B112CDBF42EE0E5D552B7E523F006B04FABB3CC97D2FE955CA1A6445A017B6C434268D8E556DF27A6001B59B0ED67557B0673A3CB00959FC70ED07E9EB413BB62F05E7EE6D289215D267ED39ABD9D8D93B0AF375C308C3D08C1DA812502F79B36ACB07F0B97A6A0A127277B72C63394BF35054B9603CDEBA40D9809B8A51637D12B4CC826961B95394635843B4BC3E721670AC7E70FD6FDF9B7533E41A1674E2A189DF133441E7D09762E58B6492873CBCB3661C62C0ED26D1C4155C7DB5D24B08B85476CD9BD4139CFAE689DBF0B6DB7E1E0EA8FF81A8E506704DCF068EBF64F50A8C97D3C127CCA57EBEADAB37E2137E74C61927ECFD24897BCD207B475422AD6B68F9A6146FF320C7AA0B2BBB9C8129DB1DC03E094CEFE88E780DFBF4775E6464F77B5D2BEEE49DC074755110FEC2F43F728F866B0B51407B6AEED48DDEA08490CA786CFC1395105A13CF2A8D654AA7583786064C5AB4C3F432D1FB0E4F4F03F9E7580F839F42F1B72EFFA5DC5D0C90B2C21BD8B93AC7D1EF1603357DBF40DCA8AB551063E2F9C0600BF731BB54D21BBDF15A210EB7E5F2B8AB02468348ECAAD15992535B5EAB1E7C486B6E97968EAE3ECAD37CE9748573673381ED892627CE2F2BEC6D709390D6DA01394DF9B42AC9508C76BA57369FFF42DFFE028596651010D507AD065239E9E00E8C797ECB6ABA2B6DFE80B724B5F9826F0642E4BCA077A8A661CE86593CCF8C685FE690224E4A3F41D15115672FA485C362D641498D655A7CB1D696711DA7F77BA414D528B1BC861199BD0562832BB8032DB885786DE6C60170F33DAC20C2618945F4744F6C6FE1B10A2E24E0443BD60B1F40D39735625725FE20C18EA6C0192E9AF47ED1EE9D23DE3B83098FE40D36D2D17986FEC683FB5411CFEB8B1A5A61E990FCF6B3BC8E32E3B1F1A4BD2C3A86C089C38B3B1266A1CCEF53B663E0F1D28A2B63F11E1E2F86BF43E7542D1EBA891DD978C8F573289933A9B182FE4CD8CA072A59C4BA15D0ADAD86F7735307F24EE01D1789666A7123C25F46B38CDB72B43F86CD5A82B97EC8916ABDCB0CC03D1751106807FBEB21D1503C3D23EDAEB255F30F252A8AE83B5C02BD34DB15A34FDBAAC51D0E60B2A415E1BF0E07CD2453C9021BECFD13C73734F7F6BFBB4145B27F53847873A948977401EB8680ABAC4FDB1A5E8D1A94E6D1A8A50E4BF2CFDCF198D804B43B053276758C51E3B0A20FFFAE94B30705A66E5F586396", + "0178BDCD5B5412B1C06884AD4CA3EB43607566114B599A22323C508578F1CCCA" + ); + yield return new + ( + MLKemAlgorithm.MLKem1024, + "06725AC358433FC95A1269AA9247169504CFF462C01771B40583CFFC91162AF4062FF70B95E2C66EE373191051215B9A29222119385EDE2C514E018A52D847E0E616752A5717F9AF8FD6C5A4001FF21497EE765EC0D040A1D16CE9EC559DB5386C5C6B77B62A341B532FD13A7AD960D80B01FC2751B0398BE7147D688B7732107871E8C71EA1B8E0ACC8B93623B9E3848BF811FD25B1AB902048191BB516CCE4564CB1715C1D1BA7E3A6CA8153951C663B8772CA3058535958758461AF57805604E49114B2751EA13760E95985003AD06C86710B4E7A231D6713CACD75309077C4B92B288C109780F27663B8389594AA84C014D54AA1692C70BEA5C36685B6C66A7D11FB0B94DBABB71C1C80C95BC9277AD0871354123C0A231D255AAFE43B2E10B92FBB99390D00AE3FA68BD938954D78BEC3C08A31A1A47C03BE2C0747F4658FDE4299A58877271A0532C46DF2DBC18C655F23041BA820AA2BF37EEE304A72A587D15A1B26FABCE164B7700C09910902A87516A41054E24AA30623206FBBCDD57612B799B3DAD37D7DBB4A8C43CAD3B0C3842980C255C0C0582D685067BA837B9C2B0997A98B57B9AF212139DC4047A572484FC8106669036DB9951E460A42A581FCBB099F015705203C8E636965EA24BCE902706C3108D7B86A410A8D808544DB34E66A6417017CA41607CC938F4DF27E621C8716F834753B959FAC7D83C76CD80C167AACA2C00B794C416D4A008DECC84163522DDCC22FE5F519485AC5B2389149A694C86B08ABCB071BF50C9C93BBE7FC565D35919714336B413F08004BCCAA4E390C50559142FE35B65D56738B003E38E59712A193165C10F0B99C80C7BCDAB7102DF68085B546581852D42683D9D070AC72672CEA16CDE5C1239136D44CC1BDC92A91098CAC6C4B66B87546B71CA0B882A102CB50E0A0530C4732228508875DA38688585357ACFA74566C48641948200048B6FB59064B620A0754BC2901B4E89BD45C47E24BC9CDC7B81375324EA28429A3C2F273611A2BC2A60B773BC21AD2353F7DF804FFF062FC426E604A894532A051B13D97120DCBAA9F97588F2F96075614BFB6C78D43610A28044CB49969CE2A923D2B6845748EEB8B7E087CCC9AEB16A4F723A4C5924787AC7212C50B488CA99B99D5F90C2603073737A6A68B111D548C66EC62F79134D17C3D3F8BACB1AA22FB3C9515E423A350CC32ACA6C29CC621486CA1992D32735962C9819BF204594AC5AC92476C418E3121A187771020219551FA1BF8A9BF5373286999A7F701835C19CB4119A8B6AA7CC2323967E90721653AA9D8620378C1BC1AA205B13BD298AF5C406ECFA8061A9493FDEB69A3714196DB126277AA9BE11077E96CE196AB2C51202CC66C20F5C354A1C95B46726A6B2FE31702633200499C9AB779090B8A6E8D9B6B1A9452E94A698FB396D87978083C867D0B79B9016ACA4906EC109C1A291AAFCA8FA77C24E3A254083AA4CEA3A370A9B01D3A10D43B487E8496075840E9901E8A0845E9B550AAD7C2F7A35D56D19FB923B130574EA25B256370341D18872D158858148BC0EC3900DD3DFC1770D2D4A790307B2AD4C60B45919BAC9DCC913C66A277ADEC19197A5EB0FCA94076515A1993961322A8D82E86B286F4013F541B15AFE8BA9538B3F6F257990BB2C37901F4A961F53191B0BC4DA684C585338D2EB0B05A373BD2BB97F7B4061295C639DA13E830BAF22266C9326DEFB4BA732A392589593A31B5106C431CF5A985DC927E5567049082B62430541829C37C9A1ED968E42232EF50441B3480C3737CB0B57F2A7A5A48687F73D148FB89C7CDC95424CBB42A186FEFAA51C20C840493360EF05070454346784EEF826C34F15FCAF9B50FB47ED0467666A4BEFF465283454A24245ABF870BCAA89D70D51334A2942F774908DBC61693070D58A6997B6A1F6B2AD1D2931C27C74304321457BA3666153B169207B89786E40C2E050B560A37503141F67420A5B05C88B54F4BD2081920C314761FBB60C85D1443E93089DCA26007D3402FA918D522C85873C80F1A041AA63C0BC65C6F86178C61C5C732225980370BE51C7F065FB4C45E3C73BE30F4A3F31BA63039577E775CC0E2B62E8A1331818BB5943A637697ADB5751E16892DF3272A638051E009CFC0831632CC388D5C54CBA8FEB8607BEE47D52B8810EA13B378160BE4DB04A59B794CA91846", + "4659824AA22A4F3454BAD00ADB48C8CAB062A10470D83A74BD6A09441B5CB1D3AD148765ED18AA202CC5841901B929871E085F3F0B4FBCA649384176E962C9CF4022DA73A66D25ABC24CB5BB196099541F238518432955D2803E29279C7108CD2CB87832386368EC9A8F07CEFDF2B291A49B164055D78840EF6256E1E6A8E4ABB87D7137FA5A2A6082B5773C2C33241B00DBCC6C60561B3C66D3D5CA3FC66044A5AD63033011FA720425A874B805B0E9A8EFC6B0F701790975A7ADD8A3E78C7FFD872274E1CAAD0A087CDB742BD440931C5E43DC9B834A6EAC3C00E96415F0407C7E75CC9A074FE04517BA85AC694771D1457C87755DC6541E05E328F3E328EA87BDEA798506103A4F68C038827E1A357097B9330AF68D39C15FA6532943F6A8BA3ABB33738C31E0A96BE3BB353BC9C955A2E2B89692F4C4C1B520849CB762F8021A408FB6BBB9D1683D7657AFBAFB8D0E185B6BC03431C6C52BC69432FB347BECC48975A015A078CC691DED516BD5900226F2B7CDE6728608808FDC0D86F02011796E4A973A0B57A3CFF25A8EAC1CADBA93CA6397E00AA5C9E979DC90C3B7F729EF9C894A4739FF69BE65EB313DB1C1834C097F75B085C16C3AEC8FF946963312B82D6292CFD658D599410F871EDF522FCF952B6343A7EAB52C59C0B1E7822E6AF63994D3896774614E6091B6132D7F8A4F05619A4213037F6BBD5CD4466593A9BC7729929031B80A8906F031CB4C3498B93294F4B769C661D2B7330511CA43E8A87A817781729E45AC219D41306FE9B63E288D724B82B2A07ADB351108C15FF3FC67A9819403DA49F29659765B6D33D18D3F0A65CD5A4B2CB58736914DD7B74ABB85A852D1BF67A1B03DFC2B5A73710249526B5835EA7CC9F17059B761886D82B891B65844678148678876D8B9D765252E0A5E8CB18A4F9120F01954FE5208905AABC7D1163300B6B2F0BCBAD81C692808FD3793A2047C033066FB55AB924245193C68F01064EF610D7DA2CE64F474988B037FD79EAEE8554EEAA077209EC51849006886264574EAB71BCD93A2A735B44E4632C0D43F39142810D10CF58812436964D5BB4487157DE703A56186C3BDE12A5F074C6D947FEB740403C27D8BE7A2AF097F553947628851E909957E428AB6E43B5DE535F8817B234244C0930E700530BFB2827C4C1DD9570D8DD86A8CC2352F97A0E1AAC353E761CD7226D6F62EBFE95EAF280EA77A237E9063CA9718C5227A9A092587CCA109062679F84F890164BE7B1DF041969648272B21C76F78A02A7617F22CB389F9640FA75E0C957431696081E0AFF3E1B71A100FB68C0E4217A706BA06A1F52C1503AA8D06A28E67BEE5CA9F5DE5B1F4C2ABBB18BCF03694C5A70812F80982B28B7336B093C56E3C042E9551AE34980EF8C7489A541DD6F6BFBB0BA25485468AEA70AC373E3F80BA883A3346614E6BB00A64B7CF0D9BB7C1B8BD18B838757673CAC9663A88BCD3E4AEDD04945DA02AAC359E4129B42665A3C284AC94C75F97D932E442629995666D93B8C43ABA34AC420F8035D529C3FF5B04A3551EA9BB75184057F1D657A4A181655427543B7DC63546C8B0CF1FF9057336B86103239BA991102968EF841632306EFD994ADDF103D80A5FC34881AA54C217460B7A6BAA753820EE8B39C6553E88575152A103B26376C49A815FC17813EC0BC82A86668B965D641C92E02292E4065E2477D2927917A197063B9F27B0B996D90AE75314DBEAC9DBABA71A1713D616BDA831895D8A4BA187C0390A979C1A7ACAB23061B7A02192C2DB372062A42BD9BB10898571F183119D0C4E72227D2284B45390A516A23502374576C906D13509DC20AEBEE88EDE13603BB0404C52549667C0CA9BCA084837850BA4A2F93B183017E0192B76B14842644FC891279349224FC9C60F3C0595A93FD00276724493684A650FC00A9E029C2CB8900DCC363F495AF6D5A5E058CB522823D9113A68433919C5ABEE896DD0110957D7CB64858AA2C76E4CD47861C21EE65AAA38AC7B7BA262EAAB2A4311935AFA35DC31696D948964B596AE12356023835C4643F158127BD321E18B084558A607CAABA52A952EDB817C176BF1A4473E2558E23A5B7DB8781DE064D6E3BF65088BA8B20BDB0B629DCA6658309C4923398A8C82D73A9FDA7C6306725AC358433FC95A1269AA9247169504CFF462C01771B40583CFFC91162AF4062FF70B95E2C66EE373191051215B9A29222119385EDE2C514E018A52D847E0E616752A5717F9AF8FD6C5A4001FF21497EE765EC0D040A1D16CE9EC559DB5386C5C6B77B62A341B532FD13A7AD960D80B01FC2751B0398BE7147D688B7732107871E8C71EA1B8E0ACC8B93623B9E3848BF811FD25B1AB902048191BB516CCE4564CB1715C1D1BA7E3A6CA8153951C663B8772CA3058535958758461AF57805604E49114B2751EA13760E95985003AD06C86710B4E7A231D6713CACD75309077C4B92B288C109780F27663B8389594AA84C014D54AA1692C70BEA5C36685B6C66A7D11FB0B94DBABB71C1C80C95BC9277AD0871354123C0A231D255AAFE43B2E10B92FBB99390D00AE3FA68BD938954D78BEC3C08A31A1A47C03BE2C0747F4658FDE4299A58877271A0532C46DF2DBC18C655F23041BA820AA2BF37EEE304A72A587D15A1B26FABCE164B7700C09910902A87516A41054E24AA30623206FBBCDD57612B799B3DAD37D7DBB4A8C43CAD3B0C3842980C255C0C0582D685067BA837B9C2B0997A98B57B9AF212139DC4047A572484FC8106669036DB9951E460A42A581FCBB099F015705203C8E636965EA24BCE902706C3108D7B86A410A8D808544DB34E66A6417017CA41607CC938F4DF27E621C8716F834753B959FAC7D83C76CD80C167AACA2C00B794C416D4A008DECC84163522DDCC22FE5F519485AC5B2389149A694C86B08ABCB071BF50C9C93BBE7FC565D35919714336B413F08004BCCAA4E390C50559142FE35B65D56738B003E38E59712A193165C10F0B99C80C7BCDAB7102DF68085B546581852D42683D9D070AC72672CEA16CDE5C1239136D44CC1BDC92A91098CAC6C4B66B87546B71CA0B882A102CB50E0A0530C4732228508875DA38688585357ACFA74566C48641948200048B6FB59064B620A0754BC2901B4E89BD45C47E24BC9CDC7B81375324EA28429A3C2F273611A2BC2A60B773BC21AD2353F7DF804FFF062FC426E604A894532A051B13D97120DCBAA9F97588F2F96075614BFB6C78D43610A28044CB49969CE2A923D2B6845748EEB8B7E087CCC9AEB16A4F723A4C5924787AC7212C50B488CA99B99D5F90C2603073737A6A68B111D548C66EC62F79134D17C3D3F8BACB1AA22FB3C9515E423A350CC32ACA6C29CC621486CA1992D32735962C9819BF204594AC5AC92476C418E3121A187771020219551FA1BF8A9BF5373286999A7F701835C19CB4119A8B6AA7CC2323967E90721653AA9D8620378C1BC1AA205B13BD298AF5C406ECFA8061A9493FDEB69A3714196DB126277AA9BE11077E96CE196AB2C51202CC66C20F5C354A1C95B46726A6B2FE31702633200499C9AB779090B8A6E8D9B6B1A9452E94A698FB396D87978083C867D0B79B9016ACA4906EC109C1A291AAFCA8FA77C24E3A254083AA4CEA3A370A9B01D3A10D43B487E8496075840E9901E8A0845E9B550AAD7C2F7A35D56D19FB923B130574EA25B256370341D18872D158858148BC0EC3900DD3DFC1770D2D4A790307B2AD4C60B45919BAC9DCC913C66A277ADEC19197A5EB0FCA94076515A1993961322A8D82E86B286F4013F541B15AFE8BA9538B3F6F257990BB2C37901F4A961F53191B0BC4DA684C585338D2EB0B05A373BD2BB97F7B4061295C639DA13E830BAF22266C9326DEFB4BA732A392589593A31B5106C431CF5A985DC927E5567049082B62430541829C37C9A1ED968E42232EF50441B3480C3737CB0B57F2A7A5A48687F73D148FB89C7CDC95424CBB42A186FEFAA51C20C840493360EF05070454346784EEF826C34F15FCAF9B50FB47ED0467666A4BEFF465283454A24245ABF870BCAA89D70D51334A2942F774908DBC61693070D58A6997B6A1F6B2AD1D2931C27C74304321457BA3666153B169207B89786E40C2E050B560A37503141F67420A5B05C88B54F4BD2081920C314761FBB60C85D1443E93089DCA26007D3402FA918D522C85873C80F1A041AA63C0BC65C6F86178C61C5C732225980370BE51C7F065FB4C45E3C73BE30F4A3F31BA63039577E775CC0E2B62E8A1331818BB5943A637697ADB5751E16892DF3272A638051E009CFC0831632CC388D5C54CBA8FEB8607BEE47D52B8810EA13B378160BE4DB04A59B794CA918460F828896B3ABB156C26BC2E37F4C2DA1608C54971206892640A8B7FE278D8A82B65351EB0FD5E4BA7378EF3C5D2A5DD4084824D6C383D2377D36484624298A81", + "5CCE7410F68738ECED68AC00E2FF78963EE06325D7E030590584A30F9B740A2F7A5CEF919F384D1801827E677C2C155089EDDDFE74471E319B7A96C74A751368354A3C5C62D517CE7C20415E6E2A9121277E039432B99244D95283B9222AAE6F675B1FEA9E9AF71D60C82B8AB74628C2C0A626E8FB7FEEB3A60B97D85EA7BBE77B3FCC85FFDCA8C4501BF7B9AF179716EC483066FA92530B63BC0FA3C296997967FA1B3D98667A350447D59B8FAD4EBDC24F80C25A525022E1CF75F497BFD0889711ACAE5B5FBA78FF0A1CBBD47A352A8709085AE4ED8D06D05A9388FDB106DB6DCD93BF21407771A66B26C1FEA1ED2D15AE345F4D8131E7F2523AD95DA91D6A143AAA08ED15577DEF0F274AE853B41AB63650E7E733D9D7E9B3643FE4CDBE607E5A7DFE75AE57BE8C91932FD5D726691FBEE44D8F83DC94A78CA87369AB35371523462D3254724CE245FA33068606AEC2B7144706A18F34793AD298229E073511EFF4062182DAA6BCEE01CD388629ABA8EEEB105BF0DAA0120BA9FF27FF95EFE6FD4842342DE27AFEBF8972CF100FC3977B2F40E851B7DD14C02E9EE9EF0A7000882718EC2055C25BED85DDDDA8FA7379A904FEB36CA89E749A54F633042FD87DD70BB261058E64F82B5DCF19CA59233EEB364BBEAEA9B71B5E475C33D811D60E7608251F2B4DFD3AF9337FF03B9956BA7F53312E1955E9A1719C3CFAA7CCEDF8AE7CD90FF4F6129967295CAABEC97644108B3C5CFFE65E55ECB93394BA5F56E94FC2720A66023A4CEF20FBE9A3B7CC6684E7ADFAC2644E7E6A735A26D5BFACB56D03BB37474DBE73E11390DA4243162EBC5F93C9CE7CD5AAAB419239C89CA62B7AB233C7688803A32751234D7313DA0A888F41C9FA98C4486AB1D474EC933993BA7C882BF6A5B459B2F8CC606C9F6445FC8DC6CEB24BC376FA9BADF1F2449346E671A584BE000278A631B42DC80A6F723F64D273BC264527247F9B6220371C05FD3F729527FFD87A7C1528A0CC6BB2E5F5E75B009B9D8F92C29CAE035CFE1C16D7B66D32CE3BFC8447BB247F62E46B96A187CCE43256C5E1A0DE4B339854D281BD0AE36D248AC25DE1419BD2E3831BD9E1F5856CED3AB7B1BC9A48B33E24DB0814AB30DB03A25BA58B4A6CC39EA45556D02C6CDF9990938C002ED43EE740E8CE2F9C9C198D287E1225A495B5A054534705D6C47E00CC997539B63433A248D6331F70888CA4FBB01084DF34A8ED1934600FF0052C2C3E25103C6B588277E0073A6DDF31772DE96C54417A75D7E1DC92821B464C5418342D96E10551C81103978D7AE960933B054B7EDEEAD4601B670B86E080B6EE898E5D225897D683AB9006F1BD97A5B99CF95A9E8EE4C7CA4078D6D31F8A3C3EE51DCAE9E87CFEFB2FBAACC39DA57579699981F637B7755393093AE7C3292B748BC26DE7B6AA6E1E06A8BA4BE5AE0D7D8EE929F533EE1306A0C59EEC0EC5A54407118E2DB2DCC2927A176B425AFC0F6AF16DC9503DFB8F66D55990FB9116E7E5EDDE67BA3F9A42746A3103BCD0E3E688639AEA6E63965524997131F9F3BEB988B1AF9D79C5948FFF35EDBB579229659F009C8E29E9ACF753907F4126FD87C8FB1395CC1F0B796E7FE67959C034030333FE6A588FBBFA4536BCA76C69C1654F1BC08914A67BFBC229D8DC1E8FCFAD86F30312F544458818335E5D912E127524905C1590E198F3474529B28F2DEF383CA2A156D808A0766CF4BC99F1730BC846DEFB1C80523639C6CCC65C252491BC37242C0DE5F1F3B0CDAFAC8438195DD2F4AD66CF7EEB47C5D37043B40B5D102BE8CEF12710EE0A3FCD3A01E30A0FBC7837E97CAE4D6AB4A57F9F126C4DE3F8FD05DF3387F3AFBC4D33AA708AE4EF76266C76B6C9C3FD7FF9205146E56CFE1BA1275D57035CCB742B4B16E52F8983AC52A7EC8736ADE8CC998B82AEA49718A9399D2F7B388D16300956ED7A42854B712BE4857FD0FB85609930106BFFD6B91989AF5CBC8A3578DBCDB43A109E0D149F54E03F5B1FE3660ADDE9B58EC6133EC3724371D1B3D356FE0B7ED1FE1E7FDAB3D1DBA4CED7527D07296E59656A678091FE69E2F569AC15DB85B47A0D8CA9F81295C96F894128C52EB1F2BA3124D4D174D58D04680EE911EAA4029CC513F80523DCA639F6AB2649B5E93ABAB36DC1B8FABE40762F842606813836C3A5C011B37FB8B77EDBC1FFB118B3AB641C0616", + "AC32764AABF8926EC41754181B2CFF101B907C0D60FB92638214AB9164E24F2F" + ); + yield return new + ( + MLKemAlgorithm.MLKem1024, + "1023C20E2CC659E9B02355287DE1643CE2155E736FDB64213825B8C5A849E261C309B69558932170C5675A53CD4F62898593A8792535A0A06187EB688C1AC90B957719BB7B3933002A95324686741AF6998074AB9CA116ABD10D3CD482BCDA03710233FEE6296C718F3EB846E3B32FCEE59E2697ACA6C4905E86260038A0635504ABEAC8B656420DD22954A62AD05CA47BF685010CAF64A020B6782C77BC8DE7FC5BE33C119452AA518C4AE5183E6AE3AE195C07D3E4372E7B77B31A737EA6017EBAA1E9E1218970B1C26926A3F758D2301E2449B917D1192987613651B404D98E8A652ADA735E92D34192B6261A52C3A56672642757669A5716A277F7DCACC7D503007D805E950DF9765643349125310742042D4AEC4CB375C8F0C043C82A72CDC73FAE372DDB301F0C684A02C94D9C415E7830255C60CAC599392FC2A63294A2FB22B72009495E3717862AA7D37C5E8A0C0A89E990F16759C54AC9D7D6911EC0BBEF342C13CB988A12452355A8EB57734D1C5B42E485E5E70C98B792C0F0A4FB0B8DF0743CA6A94A936A80A40231FEB69F688B82692356135C45E2D6B3B346B05721BB570A9329428F86074B50930AA737BEDF2C0F3D4320BBCC4CFE2AA06E8820D38B09DC477C78385AF19595F34A807E3BC558228A06E629F479603CA8B8BE49CE24A48D68DCB2D183C83116BEAE4ACCA444A60A844749C6A76BBA67B8B60E04AA4852C56A462550A74B7A4A00CB5662B735BAB6F27157D8C1801A3963F8A1CCA0269D61D273E2B6B1527A1A0B683845E68D1E50C573C3841631300FA39336F3C9AF58A2ABBAAC45274DB4CB139FA7952D7323B658496C7584B291B58A17437EA217FD1A3720CAB173515548D045F7212A93A5033F525C6AB13FEC801ABC4B22177CC409EA1A37B10B48F29A9D631962552F35D291431C6E947B664B164317F010206BBB5023542B6A9CA1E1B877F0269A77C93B7C6E7C65755847328CE2809B74A0FFC76990055D02552919144758673D6F5090DD69ADF3A283B2E0CFDDE3460C8796E7EC4F4ACCB3A9E8872EC744D705C47D3511DDA09A7E8B3867C4385FCCCBD04855DE3619D1E20E3875861A88A40F672D12179BADF5C81FDC7A18E7A5F158866A932401D057CFA363087506C6E64DE22B1DFBE3C4E0634A3CD868389A262F1261FEF19E7B818F53D703AE9B537973849D26B97A8AB1E3B2252C0143E5B3388C577B718561F9A8C19D090D17E943A8D1503B26CB67E8A7FF6C7046F5AAA1CC33EAF011C4550ACEB88C5DD2CEBE12CC0D535E14330D2445A951FB528B108CCB7922562734C59CCB4D3552C354192E8A033DB7AA0FB89AE216689054AE0DA4A8C57A0311064E7C66C15DF19836F80B4FA23825235B6043C6B8B7937D295203B9002F697BBE8859481BCFF00C5E169030D9853EB4B2B924E657A1B424F34C36D0E29A62797A4A43282D69C30C512E6B53C4E39C55C5FB3C19106F14B06E96271CB4A6CE070964368432C721BBFBEC8375434539696322670709A832DA9CA666488C06746987B78D9F348C4B4576FC90986453BA25C7931D61BAE6A31ED5D2845E86366B0C1051233CB259720F615C22E0B62DE3C06264418E1A7DCEB10803224B0D963B3062B86453457BA804BE059499AB849DEC619C101BDEFB5CACACA5B85AB045CB21CA3528090C945D432A581CB6644B7F36D88E1E0290DFD83474B6614DB5377829A21640588FAA7F0E703D0B5651178A215753141913A62E59A61AC8522CB38A705824F2918BE534529098BBBA0760DD7689AB981AC342AB0278B109838FD798C12F71C6E5B419C261CB1AC99B173AA53C5613ACC6BC41A3CBE46CCF4EF3B7F4F49940648AD6AC21F16910FD91084B2B6590B21267002492CAB7E129C64430BD4CA911A5633364E30473B3BD86945134A93A8362C206D19AB62CC96EEB4012A8C218900576A5AC77B288124A9EFD8AB362844F7D873E21B84629B01797676D25533D0C21B4400242CF06CA4A9339E8C373E28CB2CE75B12D54CF70789F5C561A5231052149607E2C17E5D0A019B95B8AA161F39A6C93E7CAA803AA437A5F34E9962D520F49B72EF34C9D7C8015A154410C29381F417ADB2698F23734CB29570853B7A962225735A85D66C0171378E1F0A52E75251B512ED061082E959E04623B0F06A5705032C33129C953A6EC2A75CC21E114F6985BFF79837B", + "E3E45344B293B119586B15BBDCD8C1DE07392B64A444B7C6ADF10FF2089257471550166042016834CB592B8689B3F55E638798CA89CAE92AAB3989A24476142CD27CA4A747D134B7F8308A928890C52767D839535ED880B90C8C004C35FB5B261EB3A6B689786E044E3C470CD6A318D8AA9BC686814B655F430AAB78276BC1893ECFF095C95BA22E9B720418CDCB65A89B6C7170971C3A78CAC6B895D0BBBABC6925F0089656D6539DA9763A107C666AC7C4F01BFEE69B6B76CEF8009F8283852EDA1DFC6CBA2B053785D79E70680DAB36096B4A851EF48949297A419125C91290A105C28D8B4C33829B7075CD4FFA323E537268372E43345930D657EDBCA5760A7E67E442D284A20B1AC7003838241C26286C41EF628DEC929746A3496AF199612C42BDF17B74BCBEEF631E2E973E8A2CA3460C20220BBD7B726ACA0C89B8ABA792621FCE1C45A5C59C0D04988DE71D027209AA4C96245974E4182042E353897817C5C6309343C2E2208F6A2BC88583049E1A9596456FB81B7F67B83C8564CA78A3B0E0FA3F46517B8C63ACD3DB2F326CB8224C8740F2347CF828E1079B8041461BC209F90A7C6256CB00FA3803375EC56CA53CE81DEFD4322FC39A5740C894C31408B88DEEE21F32F42ECFC70E8C9CBB7473428FDA0AEE13A7B549861768CD1777AD08D22992FAA0CB5B9C1A16B60032028EC5055F296FD2A83D7A5583D0D5C2A8FB5BC6560F04673457214F49D715AE466F8D3C6094C676A8B38DF4F663637A472799AFFC236D3499726B6737DADAAD964351A1295193056626E182267A0FDDB85B2DA667CD4A159E592C6A83404273AFA25C398CE3BA70EC0A36249D1385052CE41625DACE34AA42B9538544B24242AA28F8D92FA0116E52F859BA4343FAB36CCCAA6FDEA1CC2928CE3C09CD121008E4B4A965C84C6073544F06D014642BB8D106D36726241197D7ABCC1D0B165FD566ED1C73AC57B10B79CCA6FB3A04691EF04465980B58BDF51E99F4BB836061A38715640C658AE55D9D08B071A566320A8E5D120BC433A873EC21DFF814D6A65D81B19BED6BBD5D52896FA4B4C532A6CE74793384A7344BCBB87720B385C87AE12E771C1152E495BFD9312872384472BF0EC39AE1E82BDA834802524630EC03810493D55C832217CF444B29FC9A5618646635EC767AF696F0F43A388CCE21B22BF13C9431406EB0C72CF7574188872A4CF553102B5353003D4CD256FFC8ABD3C59B743ABCAB18C0B31C41A277658F3478947AAB9027163F9B211C69C13E703E9F9A1CC6229501934B90B8745C8777CDD355E808CEDE632A1B009BE178454CB985597324149670FF2836A4085357776E418061488AB066868B6144CE41FCAC8F8B8C6C975078C19A9C0517047C0EB35772AE06A72A42BDF6435809823938A2C62ED00CFC78BA27F35C74F0A353D255508456D64008F62137A31B1F869C46BE6768FB47C37D542F77E28ECFC69265320679142FEDF0C870C1A8CCA981FCD3B61FA7289E9C16D8A416A86C951662AEDD096BC3475AD0C1AD82213082503D29D8AD8B71397955A3E2294B5205BB7D438F614A574C5086636049537C6CE0A24A242B54C723AD72F167C45923161193196BB0C55111F42A758A83253A396537946DB792C0D0C3647D418041A84F029107BA5171062349E0B45F9F34359E6C6E37750329B7B5069B375A147ADDACB1734C8CA0E0A6F7CB1675073209C9BCDDC8B4C8576E82E5A55B0115C18860A1939E76D8174D7960702AA381925ED9317BE85879CBA90832DA65E1D90AFEEAC77BAA46391225C910960D7262D842A4DC7A860B8C7F79E494D393C22A323A7B64604CF05C7D8907AF3B2159B70B20E83DC1D654A08641CE7566A0BA5BD9767A8583A0564808950526A9B4401667188A89604DD618EDF521DCF89063771EC3992C784C293232280CF8B68B5248066A476CA2482942BE48DC44BAF79A6DA37FE0E32744EB92B2E74B534B26D84A0E2B5073C09A0AA8810EC1204D9A02A6E4F35EB8809B67B6427D772143B91E1AEC72DB582CAC5715D0481698598E2740491451BE81EABD97F4CF838B4DC1268ACA4B8AB4CC67C8F09B8E0A0847922AD0280EF69226AEE95459010C512B6745E1C0F77A8BF315108530595503BC7A080D32A1596D7A51CE524C1023C20E2CC659E9B02355287DE1643CE2155E736FDB64213825B8C5A849E261C309B69558932170C5675A53CD4F62898593A8792535A0A06187EB688C1AC90B957719BB7B3933002A95324686741AF6998074AB9CA116ABD10D3CD482BCDA03710233FEE6296C718F3EB846E3B32FCEE59E2697ACA6C4905E86260038A0635504ABEAC8B656420DD22954A62AD05CA47BF685010CAF64A020B6782C77BC8DE7FC5BE33C119452AA518C4AE5183E6AE3AE195C07D3E4372E7B77B31A737EA6017EBAA1E9E1218970B1C26926A3F758D2301E2449B917D1192987613651B404D98E8A652ADA735E92D34192B6261A52C3A56672642757669A5716A277F7DCACC7D503007D805E950DF9765643349125310742042D4AEC4CB375C8F0C043C82A72CDC73FAE372DDB301F0C684A02C94D9C415E7830255C60CAC599392FC2A63294A2FB22B72009495E3717862AA7D37C5E8A0C0A89E990F16759C54AC9D7D6911EC0BBEF342C13CB988A12452355A8EB57734D1C5B42E485E5E70C98B792C0F0A4FB0B8DF0743CA6A94A936A80A40231FEB69F688B82692356135C45E2D6B3B346B05721BB570A9329428F86074B50930AA737BEDF2C0F3D4320BBCC4CFE2AA06E8820D38B09DC477C78385AF19595F34A807E3BC558228A06E629F479603CA8B8BE49CE24A48D68DCB2D183C83116BEAE4ACCA444A60A844749C6A76BBA67B8B60E04AA4852C56A462550A74B7A4A00CB5662B735BAB6F27157D8C1801A3963F8A1CCA0269D61D273E2B6B1527A1A0B683845E68D1E50C573C3841631300FA39336F3C9AF58A2ABBAAC45274DB4CB139FA7952D7323B658496C7584B291B58A17437EA217FD1A3720CAB173515548D045F7212A93A5033F525C6AB13FEC801ABC4B22177CC409EA1A37B10B48F29A9D631962552F35D291431C6E947B664B164317F010206BBB5023542B6A9CA1E1B877F0269A77C93B7C6E7C65755847328CE2809B74A0FFC76990055D02552919144758673D6F5090DD69ADF3A283B2E0CFDDE3460C8796E7EC4F4ACCB3A9E8872EC744D705C47D3511DDA09A7E8B3867C4385FCCCBD04855DE3619D1E20E3875861A88A40F672D12179BADF5C81FDC7A18E7A5F158866A932401D057CFA363087506C6E64DE22B1DFBE3C4E0634A3CD868389A262F1261FEF19E7B818F53D703AE9B537973849D26B97A8AB1E3B2252C0143E5B3388C577B718561F9A8C19D090D17E943A8D1503B26CB67E8A7FF6C7046F5AAA1CC33EAF011C4550ACEB88C5DD2CEBE12CC0D535E14330D2445A951FB528B108CCB7922562734C59CCB4D3552C354192E8A033DB7AA0FB89AE216689054AE0DA4A8C57A0311064E7C66C15DF19836F80B4FA23825235B6043C6B8B7937D295203B9002F697BBE8859481BCFF00C5E169030D9853EB4B2B924E657A1B424F34C36D0E29A62797A4A43282D69C30C512E6B53C4E39C55C5FB3C19106F14B06E96271CB4A6CE070964368432C721BBFBEC8375434539696322670709A832DA9CA666488C06746987B78D9F348C4B4576FC90986453BA25C7931D61BAE6A31ED5D2845E86366B0C1051233CB259720F615C22E0B62DE3C06264418E1A7DCEB10803224B0D963B3062B86453457BA804BE059499AB849DEC619C101BDEFB5CACACA5B85AB045CB21CA3528090C945D432A581CB6644B7F36D88E1E0290DFD83474B6614DB5377829A21640588FAA7F0E703D0B5651178A215753141913A62E59A61AC8522CB38A705824F2918BE534529098BBBA0760DD7689AB981AC342AB0278B109838FD798C12F71C6E5B419C261CB1AC99B173AA53C5613ACC6BC41A3CBE46CCF4EF3B7F4F49940648AD6AC21F16910FD91084B2B6590B21267002492CAB7E129C64430BD4CA911A5633364E30473B3BD86945134A93A8362C206D19AB62CC96EEB4012A8C218900576A5AC77B288124A9EFD8AB362844F7D873E21B84629B01797676D25533D0C21B4400242CF06CA4A9339E8C373E28CB2CE75B12D54CF70789F5C561A5231052149607E2C17E5D0A019B95B8AA161F39A6C93E7CAA803AA437A5F34E9962D520F49B72EF34C9D7C8015A154410C29381F417ADB2698F23734CB29570853B7A962225735A85D66C0171378E1F0A52E75251B512ED061082E959E04623B0F06A5705032C33129C953A6EC2A75CC21E114F6985BFF79837BB476B6EBC850461C28D4AE315666DDCDF4FE185EB612397E63569AFA884E6819429BB325104E4D5A8A83A27713B50E8BDC063091B606A298AD8F4DEE24EF2483", + "B352D5A6E2EADC640865E102615DB648C648EA3B1646DDCEA1611FE6F08C7EE36E6A84E3B389BBC59CD67559E3D304AF8DC139CFE8C262134BEF89A8B2DA20F1FAC6F1059D7F49C7D53AAFEB1EC9D507A1CD171D129FCC74E757995B38023245AE175AD9E0DCE6407567AE0734676567C62E019E94A033BF75593BF8A58B907750C561218C15FE345FE27D0439331988BD61C2755D5147D8ADBA19E11B25B3598F512D7525694150444B714D900F85965C870DA505E087ABB2FB6FBB1439A0E74664F8087D341C7ADAA5EA54AFF98D725B235640D89119A0CDE2D2DB1E08C9DACD6365DE79B754D88EE9F75BC4E3357507AA652C84D5EEE042BCE3B250AB16C1E9995D2FC65F097FDF3F019378AE0DCED07EAA0DEFFDBEF2CF7F66C3522ECB7BF4CCDA07C354931A6DCF7F759A41C5DDC17A5927C8DD452325DB023B632D1D5478623E641C9845725E4031D777BDB3E886EFD091D2A654959EA841A394B2620166B0E39D5D53BF98F37F6EC45FDC10236B8704771E518FD0C9581D81C0A7801DF129BF7D8EAD32F9BF8290F90D3CFE1CBC0CD9CD0AEED6F37DF04ADB354DD18CCBBEF4100FDDE5102BFD9965B3A373E9CE47CD4208A1C6CDE562D20DBFABC45B553DC0411E6EBE45219B16DD0BFDE0F5BA8239923FAB5CC5F796BD563B75BC10D45217C1BFD05BDE23CEDE44304F3B4644CE3BD6719C258387D2F684758C6E2D89BDFFC498EA518CE47A7E188E87F64CBBED10D27732E651557855827BF8F5014E5AF3E4FF06510DEC0F7F48BEC66C9731AD5CA8D11D5C1B6B3E6C4D1024B41EA4899919927F3FBD8A3F8E89CE54BA83C8DA840611CB16A439E004D486E08B8FEEC8B0BA65EAED6A1A08FBFC4C2D63BB6A7EA0EED678197736877599AA96E8F27BFDBB9A217E97B694DB2B604F4F2CBDCE7DBDF349960B8E9A036317F7339DED78ECE6CBEA9148636AEA5A2BA7F2B84CDE87BCB656A0E4B8B5351407F9094686909B2E7DF85E425352B7F95F7ABEE4243863F9C134E1836AA281D70755F66E6A4A3B6E8A2F7765D436129F719599A0C01E9C9798CC778FC771ACD5067E9E9E1EFBA1F04C367EFCA76E9C32E1145E49A6AD2D9E2B025FDC0EC71F510B2D61C83CB7D215CD306D9EBF2D6083F19EF8ABB7B3E46A728C5A25A5333E48EB2192CCB026BAF143D62478E23953C131DB0FCEDFFF17637D685ADFCF3B994ACC831607516DCA2695283DAD5E10D3B20F9F7366F0076F227EC2448D840F32CCA52D364A1912D569BE14E74A6DC4B4543FB3411BC0C1A3BABDA8FC6F0C4D20BB36C8B5A7FC8F4104A10779AC8375CB174E1366DB213917DC4340570192C57431067C0740A86BB342DFFA8E36BEC9BF554B36839B7D1F572C12928A197403B6B7814D8BD83EC23FF35E4475C8198D7C8EB6B9AFDD4A9DA583F5F92C5C4F048594ECDADD26057BA4C989E08C8E800A9E8A7DBFF4494A33FBA336BD60789D6CAA3277823462421CAF63C2937E16CDDCC5CC0668E49F75BFB96E0293482ABE5FD188DA961EB1116B3B2D2155725A8E52D25EFE3C2D6965A2EB62A20BC640B4E172ACF6DCB2E85EA99A3E0AD711F0FB45084F3DC3C433179C4C6BE311A1909DC097C911C666F78678FFF71D342D1661F07A14AFA2DD8A6D66AEE7A4C5C4CA2B8B77DE19B53E31DC61415937B676A13BD1EADF11A7F7302022EB41E147DE8FD1C2D71DB80778B1DB2D378B211EA04F35087FCE5A98F3D2F40DB13132C4E1B3B50241A70A44E5829DBB562E350FD01283CEB743FA0C5B72A8A5835B9FDE77AA23FF6F016EABF57A256C572AD3727455A10311FD7D1DA6483C70810AA47860436CC4216A90460B0BFA8B98D49FDB3433D0EEE65356D00A05F027C4A0C9409AF72D0E1C3E89E12A383E2AD5956C5A7DB0164613467EE7404BE8025D99CDCB59D9D701B119B16F3E462978850E8DBA8AB08B88E2BDA07DA68ABD89711A086B825298C8AAC9166D6936D3E4F1E09452853EFE6700D126D17BCF6F0D82434CD9F153FAD3573E20D35BCDBAF35D664309A2B9FA21996CAA29C9B11FAA3A22467DC1E5C9A986E225D199732B5B248A38587B2D0E441989170509E693C1966DA3DEAEE35C927DB6EFBBD4486C6EC570437E3879596A1F7A3EC3F4879782F2F21CDFBA0945F99BACBADD25BF1F25B6C5B6BF853901DAB0793419C543CF52525D759C1B0E899EBBD0E994C39EC7", + "90DEDD24590FEDFF42A27AB44173E0711839EC9D15728D7A0C191CE6CE5CBC68" + ); + yield return new + ( + MLKemAlgorithm.MLKem1024, + "288A856E276D2A364E5DE2ADEA9ACFF34858698C176722CC937CBD23C9500E339CD0B03E7B071790739E68566A5C045119E9C14B41693349B2A2B728E8A3410BC3B608A47C6525A680343E2A3C056B873C8B92A6993506F1E51966677218060631E11953158511721741E74EAF91B9D5279B8FE76B698800E4763D56685B5101C219D718C7B01401C85586577394C619886375781A1AB8977A3AB97A18D8C05186486C18C53490B964C21E6B5C4940251200FB79D89295FF39C903D10A710B26317B370BDAA78C0A396C5A7B312341A57B34DF7CCBEC4CCAC412C800D25317125BA00255DB3B99AE4244DEA8B395E29C55102429F1CC8BE854BB7272A1B26AEDCBC863666193DB3397C87397B744C3D9B43E58262716AEA81422D779C4FC60C0B82576D149C630AAB7429B3ECAD23F42219C7BC348F10052824C63CBB5B5F39B7919084E6C344F23B18DA3E1630C2427A7A526A0D26B57319E1870754C7854A4E2254D64AEBE8566A4FA13F890A01C046D356AC0AFCB6514E0038D47CA01D96432922379E16637798006476183F0BA5D516B6A4AA143C9484318A6D0970150D530B347BD53A0AFA587320BF1162D2B21CB4C9826942002628BD9A5699682AB56B83C4F5AB112815A8089805B305720E55E104C68CC1B7EF8C3916CA3581EE16730C786FBE35D7FF017251549EC88A5DF5A93AAE44F60962B2A2549442A2DCCA7107D96C4C0028FD32ABA32A146FFB2832CF246F66C6B3E500B2FD0886EF52ADF58B86C6C6CEF046A67F107DFB24595BC996631C81DE0684AD5A248C6A869807D460A44DBFA8A060B6A69E13EC37A0DF7A7572F573D1CCB3118A2B1D6D337EF33AFD8EC90AA08CC24B39C1B92018B7002B7A970A07A7DA1B8AB8DE1ADB01745BA159BD111421569792960394CB7AD711C941540716F6A4836AB5AC785A1297426D235CC001B35D040506A46264E92A6E47AABF23261D2A45E11516D73C5331B2A4F60E3007DC12A100C2068FC29EF5B82E4EA7239F316173B259D03B2C64254ABD52F3F498268691D0D61CAEB16CCA57929EBF88DDDC00FB632831194499CEB8231E77BE2DA5132136FFCACB633B6332AF25B224857D5B72D07922C8A5C26E6C76F31888BBF3B5F8C29AD06D57AA9841E9B22249BB1639A5243BCCA5293F2990C4C5149545D0C7C0D5F0299EB361DDB285CC577C8426565177C89BE0AA674EAB947E7257D745CC02BBFA815A34AA3155D9AB773094FC61B15E98595BA685A207A3D92902E943C585E7521B0D39450C1C812E2710048C978FA54D53A267568444F139F2D5A97BD23B12860A835E74D773B20AA668BD9E02E601CBEE8A3AA4DB119492028CAA4ABA50C1FBA3426C99BB6958A8B34A0A7B32C6668D32176B16CFBCA137F2964D56A643F888F955CC25D22103A9396CC133F01A99F29145785AC5F3BF42C7FFCADF5C30F9457012C36BBAA9C56AB917660762A7ABA25C3F1AED2EA2CB75214F1D798672A89EBD74285D8B3F51801F77693CD0C20DF48ADB38B6696A1AB4EE804D7A02A41B5928A1C2A0786B7C867493CF28AF62C927644154B1942C1880C593A4770DC303594461F583C590A9D268B4E0B671F12593227B609B07A3924FB5D439A64921821E2079D9323A977CB9C10590008FCCEB745151D4A0C9AECC62E7C6754B2887C566CBC20C004D546A01BA09F92273592AF9971B28FE5CD84974196E79D684962449A8D54560B8B57BDC386ABA1674CB3B30AB76BB0CAF135D023B20776487DFB20707636A9C21022C104DDC51D0CAA9069948AF89CBB80C90BA027BA60E319F1B7B563695197F4120A26CF81C51C208B4A7A054B03C3AE624096CA2C5CE9B20693EA0067688193EC626F39C474C9B070A3BB8414C7BD6897C9BB1489F3BFAED6461AEB3098F7CEBEDA12EF007F7F915D7374312CA581DE8524422BA2A5310E5A96003EA86826C815FDB6AB4FFA7000783A9D3A379F79B235A204B94A21499AA0C959CE3E25B7DEB9720CE97B604B2B4F31CECC75C3BCF469F61AAE553352479C8E0237A7DEFB42F349013BE6AB6CE7AF7C144E481B245FE2303FB230AE3462D4B3ABEF3AA227F4AE652AB82944444FA1389B720BED57647F93947E5886F70598B002A6E087A736576964331CFB256FF3E13AB181980F26867C0C7F094141522A3F82A9CCA8DACFFEC23BD7973211C4F6244D2D2AD2BEE8EA", + "63066A49C505A3D548D5B348D4FA84E06B3CC95B8B0CB08289B28AF7AC49C7E6382779351B27616DA67D79432BAEE32595FA789E7371E6F339B22B68415B844C0074ED2279D3A22C6A62C91940760047CDCE9C71E4680472A0C12BB951E5EBA58A542F259367DB13263CC1862964B2383960D8568C692463E996665AB98C7B65C8B958BE3F26CAC855A2780B6DCB4AA49950264DCB70F35705FC28CED4DA10FD1716E0C85DCA17BA85F60BB54A514C89458ABCBFB95A131C912A4F89A3BD54CC434663F3888D8C86740B62870B07B6FAEA30C3623C8D4A677976BB7574BE32336BAE6B4210C48BE50411EEAC7D40EBA8F69A246C5489AA998B2F56C0CB8CA4DA16B1A649A41B94CC00BD6420B4CE356137B441559CCBB6B729A1912107183231D802A575D590BF6A7388E2AACD521930191237628F6F1147550B21CD574D3EBB04E5A12D5D8C2C9E223EDF66B9FDE9986503263435A070860B9E4AC5F22A0C5287A7520797D969555A70C5F54CB5AA06BC8AC253729B5BC205CD22713645455E674651CD3327680893DCD53C726B67A3806349C102C68070C5E56D8B601959FBAFDB8943E0A63C42002E3D29AE59271725F92A85A07F2F347D824C1AF68BB6E242B2466065C791903371A702C4AB99D44A79002FB8540149F6616398A3F2883D63DBB964106C828A56A4481DF1A03DB6765AE474A031787141E96ABAA02C2533826BF43861F5798D2B57D5614641993F9190910F731FE3130304E12D6F388088401BF6DB3314B2630BC322678165F1886DCA34CA81616F7FEA844C01514BA9AB42A2C23901930CC365978A9E4545776C779100784D5DA3986EE677329A4F45991A24B57C18CB7AB1187AE620761EA08F14976E320B4BBB8B1A11FCCFFD6A440FA358C395BB1BA7346B3B426821C8144A48D93A9124422154D430B4167EB09B2236B8C46557BFB545B488F80875733B013811F049642DE483303ABC8F43BB0D884CEB8C5F539C9073E488B95A19A4F107559BC056533B409B9C32EC14E35C8F05730A59272399A5626F13C2A20198F54460F8A689BFB101C3C5631F61CA8EF61774BB51EF3AC20E16BC11FC097F055B45C13911ACC37646AA5E4C3B6B98A6BD82447E83B331289797216AF4824725C7C809768C2EE56AAB991F84C1056A069255F0B8F14852F8F5C6A6F47849D7BC667A44F488B66918294A084B7A47C18433198AA24AE0B516D8CAC18BA5AB03E82F607701C53C450812947807CDCA4A088EF37AEAC3B7C3B885515BA0E34593A42C221A74720864B673E792D030BD161C86C8564D3F3C3DCB04C930EC68D42A4BFEB90270FB182A9371E6588C2457B345C1B4E139BE87008A1B572598BB5244222363B86C46095C23F4084B4B24FED715A72452D2B349EB8BA0C68B491CB371F363682BB1A237F2BB424C140A0A59D3700755520DBF6330D8025A59D69EFB698CCF99C318C44AFF16B8DBD1183EE04FD12822F3259089F1CEE382AD118972AD7C6FB6D845E781C75EC87A68905EC2257A1BAA89569A2BFBF55936781B0B3A398658085EE840D03878A447B7D9C64378EA07E5C61AF6D319BAD88503790FBB980F5BF75C114600AD267A6FA1673EB7899035A0D5AB3B34119CA919574A36AA4651192A593D62D8BE1ECA2B0AC67906F3464545C522C73E052673339901A6969933739E567C622C694176979297644E87C9701AC98473C99E17A04A93EC1EC26A6A424AB1400BBF04A7183837824963372030462E47205324CB8CEAA60A248479C633CE596A61A8CB1AA9C8C2E344BE548F4CD97DBD3A516975574BFC62E9E1383667B5FE393481A434068B0E4D800BC8207CDC7B06CBF9297A6758D7F2063ABAC2FE7652C2FA86EF995B83AC16CABCAE7DE250506A5367E9452DD548AC6A55C9F886CC8B1B9536AA14C9CBC98B7CDAF9A6AC725D258B610E10B369411BA550598C3AB928665E0F13CBEDF63F1656C2793B0C1EB9989D98ACD8D45FB29A0BA532A0B1E62292A77AC8D4BC254B1A0A87C7E961C9F7612927E514DB2AC9158A1823339415C50E6D355596B48873FC159B3C3846D211EA481E87FC2196663B5C1184717508F7A5C13F7323EF62AEF58456AC960E4E9C4BDD5670FDE441C5A6A867A216C4977CC6656BFC7C195ECB3D9D77706C0253288A856E276D2A364E5DE2ADEA9ACFF34858698C176722CC937CBD23C9500E339CD0B03E7B071790739E68566A5C045119E9C14B41693349B2A2B728E8A3410BC3B608A47C6525A680343E2A3C056B873C8B92A6993506F1E51966677218060631E11953158511721741E74EAF91B9D5279B8FE76B698800E4763D56685B5101C219D718C7B01401C85586577394C619886375781A1AB8977A3AB97A18D8C05186486C18C53490B964C21E6B5C4940251200FB79D89295FF39C903D10A710B26317B370BDAA78C0A396C5A7B312341A57B34DF7CCBEC4CCAC412C800D25317125BA00255DB3B99AE4244DEA8B395E29C55102429F1CC8BE854BB7272A1B26AEDCBC863666193DB3397C87397B744C3D9B43E58262716AEA81422D779C4FC60C0B82576D149C630AAB7429B3ECAD23F42219C7BC348F10052824C63CBB5B5F39B7919084E6C344F23B18DA3E1630C2427A7A526A0D26B57319E1870754C7854A4E2254D64AEBE8566A4FA13F890A01C046D356AC0AFCB6514E0038D47CA01D96432922379E16637798006476183F0BA5D516B6A4AA143C9484318A6D0970150D530B347BD53A0AFA587320BF1162D2B21CB4C9826942002628BD9A5699682AB56B83C4F5AB112815A8089805B305720E55E104C68CC1B7EF8C3916CA3581EE16730C786FBE35D7FF017251549EC88A5DF5A93AAE44F60962B2A2549442A2DCCA7107D96C4C0028FD32ABA32A146FFB2832CF246F66C6B3E500B2FD0886EF52ADF58B86C6C6CEF046A67F107DFB24595BC996631C81DE0684AD5A248C6A869807D460A44DBFA8A060B6A69E13EC37A0DF7A7572F573D1CCB3118A2B1D6D337EF33AFD8EC90AA08CC24B39C1B92018B7002B7A970A07A7DA1B8AB8DE1ADB01745BA159BD111421569792960394CB7AD711C941540716F6A4836AB5AC785A1297426D235CC001B35D040506A46264E92A6E47AABF23261D2A45E11516D73C5331B2A4F60E3007DC12A100C2068FC29EF5B82E4EA7239F316173B259D03B2C64254ABD52F3F498268691D0D61CAEB16CCA57929EBF88DDDC00FB632831194499CEB8231E77BE2DA5132136FFCACB633B6332AF25B224857D5B72D07922C8A5C26E6C76F31888BBF3B5F8C29AD06D57AA9841E9B22249BB1639A5243BCCA5293F2990C4C5149545D0C7C0D5F0299EB361DDB285CC577C8426565177C89BE0AA674EAB947E7257D745CC02BBFA815A34AA3155D9AB773094FC61B15E98595BA685A207A3D92902E943C585E7521B0D39450C1C812E2710048C978FA54D53A267568444F139F2D5A97BD23B12860A835E74D773B20AA668BD9E02E601CBEE8A3AA4DB119492028CAA4ABA50C1FBA3426C99BB6958A8B34A0A7B32C6668D32176B16CFBCA137F2964D56A643F888F955CC25D22103A9396CC133F01A99F29145785AC5F3BF42C7FFCADF5C30F9457012C36BBAA9C56AB917660762A7ABA25C3F1AED2EA2CB75214F1D798672A89EBD74285D8B3F51801F77693CD0C20DF48ADB38B6696A1AB4EE804D7A02A41B5928A1C2A0786B7C867493CF28AF62C927644154B1942C1880C593A4770DC303594461F583C590A9D268B4E0B671F12593227B609B07A3924FB5D439A64921821E2079D9323A977CB9C10590008FCCEB745151D4A0C9AECC62E7C6754B2887C566CBC20C004D546A01BA09F92273592AF9971B28FE5CD84974196E79D684962449A8D54560B8B57BDC386ABA1674CB3B30AB76BB0CAF135D023B20776487DFB20707636A9C21022C104DDC51D0CAA9069948AF89CBB80C90BA027BA60E319F1B7B563695197F4120A26CF81C51C208B4A7A054B03C3AE624096CA2C5CE9B20693EA0067688193EC626F39C474C9B070A3BB8414C7BD6897C9BB1489F3BFAED6461AEB3098F7CEBEDA12EF007F7F915D7374312CA581DE8524422BA2A5310E5A96003EA86826C815FDB6AB4FFA7000783A9D3A379F79B235A204B94A21499AA0C959CE3E25B7DEB9720CE97B604B2B4F31CECC75C3BCF469F61AAE553352479C8E0237A7DEFB42F349013BE6AB6CE7AF7C144E481B245FE2303FB230AE3462D4B3ABEF3AA227F4AE652AB82944444FA1389B720BED57647F93947E5886F70598B002A6E087A736576964331CFB256FF3E13AB181980F26867C0C7F094141522A3F82A9CCA8DACFFEC23BD7973211C4F6244D2D2AD2BEE8EA1D776B957BB96078F974576554C53D94D059A55CBC2D02DA6A1BF230E9B31489ED499373F94B10D8C54D1F41676E47A6C251D23C69ADABA915F4E182D6AB33E3", + "848A038059ACB8EA4514933732F43E117B6320F3EB4953E27CCB3DF2A789A09264CC77577489110F2EBC6B5CBC57D2BD73891D73A3763A37E88A8D58A37D187016507C619466726974303AA72A5461B720B862F86F84124302844377588D942F74951739E9C4A8BB282520A166CB1188747FAB13F87BEDB230EB7A8820D85C995546D7C7659A5FE19894F3C59D45D4595E31F655E55190F5F31B7FD325E44A62B9388055666AFC6C918C70F5FD7F9EF50A8365EA996286CCD994E3FD8AC963E4871BE0FDE74C9F76AE07D7886E03C8A821129C6AB2AA06B2D8034846DDF12948487E5C209744F62FBF4D71BD492DBB1F8AD108AF5B117181C5BEE77C2C8D23D0BF806B367FDF051D6A569F02D07BB3580C10E582A8243EDC3C8ED4E320DD8083F88ACBEE4B4A5EFF2038568477DF25C2E38D26161A6A7FE94DD8FE6F9B7862FE5FEC4B3AFAA93F4007A7F75A2D2CF06CF700F7768F5B14A35415676B36230752546FD734FF1F512DC1852029A5F56F961BDD0E8444A800AD645A0428650416AC09399A7105B5B4D8CBD77501560048D1AD5D5EEDCF1D3FE0D756D25D82BE7F97F744764FFFE89E900D0BDFAF21A2085D560DF3B8D6FD5E19C9A5D298E1D806627E60804F5D6E61E2C241C59DA317DFC67D18AC3C62F613973526D7DFEFF7F99849BF54449941924FF8CD6CDBFDAF972F8A2B9B439BB25B7BBA1A6381515135A6728B2B2389BAFA02490E3DA005BDBC508787AE2D67D23F226A55A9504C77D0D61FF8492DE5F3B7C9E8E4340DDC8D2A9E99101A1FC85E3CA3A6AD0BAF443C7F55F1A857075367563998B0CD14FC003E970D036277F6EC62278AFC43B1D6B66C539BD8B1D6C1DE18B46CF75D124A67E4BFEF32F3D5FB70BF94CAA1FFE13D0A2023C0EA84631011B50294ACA5364AE3C95EFBD266459CF225F7494272F5487EC90D42683B45A6D4EF2327899843EC9D8C8D2D0CC1550CD0B200AC62976FD322C8830A16028680EC77D97D09AF15EE24F23D977E16E4962F42BB7C2396F6B057742435235D38C3BE0E51FA5454045245F39B7CEDBB864CDBA6A7B23EA65FD406F80A7132467A1937C4C5468C7AA52B556A9649234265A22C1867EB898A230A193E10376984CA92221783395E49A5241A5FFFE049920EAA8EE1692C9645F114992B25F912D8AC695E7AF2D737065BDEC09D0F5B5C2611017658E1E9A7B66995B672E04C8522026C94C8355D15112786213D7D56BC16243D1C642536C00DA2851A7EFD334D7494350BBDE57F2F5F6967ABB6004000747256306FCCBBB06D34289E98F066D67129F6A07C4EB45BAF3CAACBFC423A9217C8932C701CF8402BBCACDB8AAA0C67EF39688CF85B08B62F09587249891585EAFE3A7E723C21C4C23135A8961BAE67ED41615C6A32740F02BA8A419379F5C8554B8E6E4760274A2703995CB24896CC00DD2E2C8531EF56544F7A1B25E2D1BB76AC282BD116BE64562CE433B74077B376CE437E5263793EF65DE101277FAEA6CFE1CB18A5B3CC18FD03CCEBC40A74D9F46EC8B9BE0E45A417E296AB6AC1F867013AD534EFCD8805D34B99248A8B446429DEB4B45AE27822756A55166954D05765AB5D9B962E49A0EFA1EDA4FB006745B9602E1DF2F3AF22A165BCA4134CAF0D2199FD3515BEE853ED258B80B934BC94CECFA762347CE6974803BCDB360117484D04F8772D975ACB2AB025D45CD4261AA4A5608E63F1764DE6A38B107BF5DD28C2B578FE0BC9FB36DE9AD31FFE91DC21FB505A1C8511CC2B64C0F3853A3A07AB57CE2053763421153908B94DFDD3CF3E3FEE6EB382CA6B99F977A01A4B1EE53D9BE240EEB76872618C0A90DBB0A8346A63DC04AEEEEA8D6B6AAED016E0DA7D06180AE171A60541ECE6488E39DA4215DCC405A84C4B2A70572013C1A33EBC7016ADA7BECB09DA91014425CBF0DF5AA3B0F2E76CCC4CF8BB239601D4BB6AE7C60568822D963C3635B093A5263C035E446340D81D6BF3CE82672CB9F2643C0C9B12D4AD3D05F9E8567CD821A882AD6B034648AD6975A896F12BB00210D5B6591E484ED3C15DB97C869EAB167C860F03B3EDFD7AECC9FFCE49D78F68B048245B88819A9434BDDA676B0B6614C13DD5C8621F21AD1AB84AEB2F658A24BA0AC9C291BAB982EE2DEF7AFA79AD57901D36115803F04EDA0029E15BB3A16123FD74A0603EE718AB5A51E3B688E023554A1398", + "F255E47BC336EEFDEC3B8871881B26A60BA848E004976F97381F5BEDB5F467DD" ); yield return new ( MLKemAlgorithm.MLKem1024, - "C1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7", - "13E490ADD15409C73E2BC9B0496A9513FC89D3857C5E0A9661E8B8CDA9B3B0B81778863940AA9A970123BE3ACF07E97BCC397BF9E6C245029ED518BA64A20AA1E8154C3C736A1C17B43770AE695C38E96B6EE270DE3C81228497E74206272124E3112FCF7ABE938B9B8B51B874FC4362066559C6AA41E462F912026726377BF6681431BCC5D6AE9567230A5681E3192AA6586031DA7A41891C0FE61F9041C475D33570F2AEBFE03910C43B28E549E5C1C21BE2146352CAE4A66FF8D9ABD769963D93BB6F7C8E1856B2DB4311468645C3D8A824720D2FB93CA547A0A7BB15DB3B6A6E04367837AA378734A88064E033C9B8295099F336B1A80493FB8129F79640D263E943B6E535AAD7459F657A59A1CB12B19C8121F15310357D9125825D745F3C6B788DCA96F743C0F7DA9C033A6F2C8A9F998277F1B053756166DB866D2C2AC427E85AF361C7DED10D292A5F876C8B228A655871BA227C1A56B98B8B962F233C3A570A98A01600296249E64ABD84C70CFE91050CBA61D3588406E7A7A1CB199D07862D65C9F617433D173E557B385FD86EB3A642C75494E2273FC7B904E66B4E58B97CD82549A4635070224E5E039D76E7CC055872A356529E39A27E160D64570B5C92A9B9513A6670A227F7C9CEB3450F55B2AC50C1155AA1611A5DED59A069F43B9E3A9E4DC70F4D1164C830AD7BAB499491115D9201518B60CE8175F43327F8756E3DE2B34F653FC4933381F64EF9926D30686FF981C860A517040BB9EE140D0B541FFCE389F1F51DBB4CB51AC393DFEA5B6A55500D3C305EF88112985E623205516807AB1664CC8ABCC107583B8BB3E2E585F95B89AEDB45E5278C4D7B0960355307453E4A954B51B0A6E817CC16AB1D47839095798E6F7C53EB9BBDFDD0B5005C244774BF3AFA35810226E5D4C7C194C285CB8BD6DC2800963D2C1C7204B43B7290ABE6C17AED934D50F538AEDA48F28527DEF27C331B9F122C2941B884C2BC3E950C1A15A6AD5CD17623339C09872FB899245FB18EF879C5B53602C9436A15B79324753A9090851C3184F699CF75E0648AE1849E401385706521219DAFC8326CE8968BBCA21FC059E62963A532A096DA91457427C2A65B45C22E06038429B52B5F732C87C053E2AB38E67457F3EB967F402B7E0762AE4507AFE1196F22AE9E6797BE959D69DBA5B6FA6493E84EE8B3807FBABAD2C07180D8877F17CA92E08E0356CDCCFA9B9ED6268D19196E0BBD14693BFE72510F6151A9407338128449D3806C230B617525E9E01290AA21EB8BC8C70AC60028492A79B354407F5B8C786239368800C1B2D412DC6B14FA9226D1E765BE1780C0C346BCE1147D692A0BF195A1A2CACB75C1076B59222B214F682B8DEB7B7F51BF7BD9C775AA5474C4CE52963C546170B5539DC39C6ECB963D9C260D7253CF99F404DD49BFB7B4C3A90726B3692704910CFFA2AB8AE528D2A944E80735FE25917F960FC9D1014AAC200380A3591638ECBB44F5975708F584C0C392F2A20D2D1B698706853E28117C9139F303AF622286BE0176AB91812C962BA1C311AA9AA8F334C387424177EA6564EB318F832A68C11DA2418FB4BB6B74F1736955CAFE3170CB467F19F5CBEA7A8CC93692A3673CCD8450AA85860AA04BD4EB8008E63EDAE0A32C4413B3242AA9EB1E94371D8A02BA93173BBC93840EC2347560AED85A97D3DBBF0D7CA052635C794B824BD66798E01E70929FB1CBB81E865E0819749B92063EA99DED733751024A143339ACBA3BC9B065A19006E28B522D2A10B22B325E723E6804A2F19270C5744B1754A13B2128F1C3BE87D3968C8213E5B55442E6749FB21C49396B0B427C030A3D9F397525D8B8953B945C132E5B506B5130708A55C41D8B9F7C9B0781D5340D029E538378640A1A57340DE7697A8CD37B58C64FBD7518F55AA276650C94B40C71B435FC83927740222BA32BD8947B7FE3277D9301B1524ECB735EA358AB6BC41682728DA25B70D1AA2E35A4606BA27351A54C88353A3D455651C3118AA578C4B19C557A6DC1B290AB2C97CCF96665C10FBB67A935477168E0185ACC1155A0132011C4F2523732373BD5425AFA7C061BC66C7883803039296C989224A0BDE9BC4B8B6698EABC6C40A10A842C697B3873D84BBCE048B69DC705E6A7BB6C813BC1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7D26129D71267870D23C3FCBA53A325F5F4EFDD0818753D68930C0C2797E74DD2FA9550567AC47E70FE9D84F482BDAB1A8CC149AA7889E4ABF8ED76F68D624DE6", - "766DD902E7CEF070AF64F46A73AB46A62DFB60F93592EEE73FC5542B0A057F7AA182C01CB65197D87546ABB8AE3B2412CFC89C762F3D1DB07D2B8BB4B0A714383D8913BF2C2217AD0E18166D86FD645290C705906CF31AFF16A63CF7E6CC0C7CBC75B5ED4358611658ADAED95C84347CA582A8B2E50D8A2C33966BC47BDAD9D473BF455B4B5E9E238B9352FCFF07D21A3E8BBB4BE27825111E8B10CAB55B44C6F7A0F28044A0AB2BD460262D31A31F43140FF54A7B8994979D6784FEDF6AFA278C0B0ACFF94460123E8CF08D3417481782196899FEB79B614C3C5A24328CAD9AE5937C0771BD49BA8E682EDE7E24296BD1069CB15217C962045FC246295F479FF6D2FE30AF64341E1BB786F903FAF2476F1C6D8D0051E66AE35A63C71206D4D4D9E3879EDCB10905AE914267330D781A7A4BA25B51C7E47DAE067BD25FFBF585DC99D8B60DCF106B22AEF1346A76EF7A887B62B54BE14CD7A1E84362BDB615B03AF33ABB6B06D4628D43AF197DC99F749EF0D3BDA839EC5EBB48736A56A62032C4486670026A7C9D3DCFE04982F02D1DB462FAF5A6DAD1AAC0C6B38DB644F607EAF69CA5790EAA1361D5E1FA1A8C8116A874236D25A55E9218FFAFC8AA8F752334ABD574F01CC324DBA192EAEE5B13668E253880445E58542C50CA8B048FA89637BAD44CD5CBF4C12CBF13B9D00E5297B25137D045D8BD33DBADBB3B9AE5C433F962081177CD8CC523FDBAD322D8562259B06E5CD925B8521930B90BE6357C75CDFBD3DC32762C73260FBFD534789EBE97BF30F0E3F1A968D92AC2D12A0AB3D05164F2CBDFCAF7FC7BE60CD758233303524ED3716E4DAC9ABAB3A01C86A4EF8818CA787E5AEBCEFE18D8223BBC1E70CF276729E50B7D1498964A572AF6F5800B513B8ED49C6CAEF578D6230689D061D70301565E296D9D27055296C93A9308C7F94B3941948F509EF817309CC742D7C0E079F731FB6C6AD4535203D8423722152F2A9AD0E00BE0AF94CF5FD58BFD0E3E720CF1BA7A7566DD350FFF8C1DE97570FD6894A0D3B5E23343D902A81FE23AB3A19C5D1AD08800CBEB667E05054DC749B663052E57D9A97194BF2CBB153BE50B9BFB3ECDC88ACD756DC9FBB717A3B544AAA6D0F289D436F7F2F96E4D20A7D2748687E1C55F1D416DC9A0B51C6318925A621CDBE80A5400326168DEB50DD39BF0EF2073C6573B753C55E5B352B5F69942FABE9D34DC59D70BB349FF01430A69C54A7D7F33333B112DB2E559DC5971273BB9BCFC7E7779506BCB1C51003B11AE1FA6F33537F44CAE9CC50F74DCF0B61FC01A89090CFA56460F9224A575D6C073DE405CB69E559901284943CAFFD04F4F252051B70A0A18AFA18526403FE4417BBFEAF27AA98B92066709669EB6901E33817EAF46B83AB8FE89035F34E38E135ADD10D86194C51CFCB3350AD051FE506C92DFAB055E7594AA49C151605F5FC45698AC0B780F2005B19132C6B56E40C341D4C918E73DB18BFC9468C998BBFB1B6F872C2DD0806DC57CCFB9AE5CB7DADA91C29AABAD1C03A0DB4452EF62734994CD3CE74C58445A491623C2F6194AB5B7BA8387CE1C0A0905E24FB2738182DBE0FB24822A022DD51E63DDC4016A08364E5E2E77D2C05DC1636972599AEF1357325612218DA843302196E7DF43D9D81568051548096284C51FC676C9806C2F2FE40033641E1945260F3E9E2E52A5CC307F48F72F6B673E5BAD14023E4076EA2494EFA47278D734AC5751EA4A86C155C39E6491EC614E3C4FD6AD53D74BE932361B3F4F8290D0603FA7076D452A1CFC77B178F69F5609A7B37BB5701B9A46B4D321385EFE772EBDBB8A0CA01293C77AA0C7571B3F594827E4FE7A1CEA31642BA197BB8187CC31D539574803A7603796AE02728370B2A1A35334B1D9DB5F6363EEED00D70311542C88F9D041DEAD6BD1399F46E0C0381F030C68C84E0F4251349E8039BCED39DB028B95A96BCCECEE7097FBFF9B6B9A679DA6C191B82385EA00A8C07E8A395470238D5A1198DDE7F0A9C5A91A1E4D7C35ACFCCDBC5FBB029ED17B0415ED954ACF25A3184A5309B74421E059EF2C9A864051E35FBACE79A7F85023E2442E3647BB6A795DB6D1A667497A3925ED5BBDAB3D801311C5825DB4E10B667572C5DAA81FD1A5A8C013B9D02B78D8CF2CAC9CD0E7B8735A6732754D6D7AF1254EBE066264586D93EBACDFA434B8CF29D400", - "02BFD61BE5523C69628AC9154794B2DBCB45FF5A8671C8D5A95EAF9414865943" + "6A90974F34A78A186903DA0EAE76C0D1A903D83903BA107521096B9BBC2B82268A3D897428968216362017F967866598D8A1559D067FCDA8018A7245ECDB70BF96738EE7873E146D2E9715A6ABBA07413FF9F902A3D966D3C794FAC83D7937034DB0CE645B0CE8040AF9A5A8713503F07154945C0BA8059780557A0A1B8475681FF1B73FEE227091D377782993299C02F5E9A58291A7403C8620A401459BB01643C623590B685BC2FFF28B2806613E2926C8A802B51CB8ED1005ACB255DF5006CE373C83C54E3CE15977BC8C8E7515498A3F1B58594A2248B4F450F6879FEE66C214BA4C65D586E1EC0E44D8445DBC8A60755459D1C29D3A25D753C54D721D248102D9B171823232767C5F4CD73EDC3553F2F1BA940096EF154EBB6700F4218CA9405F918996681C59897C868BD56E5483376A89649393B7B6E3BB53C9701BA02278877A53546E6B38008555A81CA91F47E05B40348E2A16CAE03507F66BACEE8741ED1B38704267CD7C29ECF13F9BB072C81A716E89651D575D6FAB5FDEBBC0C9860FFFCAA19399C690B2184EBB8EF4F2A8FFC149B5985C7B3AA0ECF64B13EA38013B5701B49004052DCEC7BF1044C800F86B5CE1317F285673985DEB34588FEC259683C7B08382A877AAFFCCCB06B21CE7839607CC2E7A13B7B5268FD314424740864FC10B5552641FAA410FC633F9030DB1602A8487A664F252F1E1936C647912D8205DA16CFC9A6F89622F3BA4BBEF22343F408C6FB25F90037944E057925C05E7CCBCD02041E1CB9C029B9B125582E4F7B62D3243A5ACB50C50364B27341B9C2E101742CE8927BE7B8933F6027B2145DAAA311FC3C6DE80441DD47092336BD834BD77A2A5974156227ACB24252C0FB35616015D2CC6CC33E9328A49868AB630F1CC14D8530BF0A68DA1D244AD960FDE1A63BB880F5BF67A4D8889D7102851E85D80130B344181A69C23FB34620A9ACA78C124718982940AB57C570CCD7368E3B8BFE47A6ED0F838929BC68E558296FC1E0ED46B9C401F7068B1ECD28626F37779B3C950B914D7447D041C79AA1C72550B08FDB13829D05692406D57DA181E772C2C79329BE81DB20B8807CA460DBC1B68A49E4181CBCBFC1924DA167F9202A777B71E7B794B0B8FF54375FCB4231B648B3AC229CA9C1215168553A6CD1EB9AFCD299C0A96266AE09C06DA5641FB72B15B9F26D79FACE24C26E67A33B28B1A80538AC9BA943A7EE239AB6E3349D65674E9212ECF7762DBD0A23119AF810897FF331970E0667BF07999A531B596B0D4116B24476BDB9757D4B67BFC99A4D3282BF415A544753934552A1C0519A132C84804803CFC2721A62D848A07DED647B0246947D003B5D014C44BBDB4D3BFC068C099364495937224216B6DFB79DC870686E5A5CBBC366268B8CD24A3CF6101C2D6537C57252155AAE570BBCD958D25D51BE95B545A24AD29D6355C34A81E758DE7E671B932A9ABA80987E63781DB367CC0CED8987C688428416625A97C77DD3251726716D375B0FFD8836D6A606DFC7A92A727CFD0BD5179A55E6206BF83983E756BC150B9BEF52D127226A106C8076B91EBA32B4384224F970FF0393936E89AA04B864ED73572194A628A053D526F5FEB580C4270F1226D1EE907B047791210B3E388B0753970957706F1864FB7EC2A314B812494AD9A3B6F82C567ACAC2DDAD6A05D720D8EE80819CB47819A21B64C0633644CF230BAD92920B451711C286A04BBAE34E1B55E737F487B37D33274B591272F562E271A884854AC3D2C35E2949937E0550D10854B4613FED929972A240DE08A2BBC76FDFCBD13F91C3F074EA6FB814289739FFB464D7CB9CAD280DB16B35C23548D7C0C44C76541B701F99AAC04BB1743B467788A836DB96E3D530CC3929FC424705A8632F1B437DC45B86B3328B15B1CD862455D991E14699537EB94E766B509D1CEBFE411E3D14B92099A803250F5466397B2439BFA159BE250E7D14A72E4CFCCD24AA4998EC775A8E031B9691980F50A0407CA221DCBC3880C3A25A54164D6913D016B63D27B66434BEA65C80F3A753C57318EF98D36A80272A0AA7148C8761170AC97979094AFC5485FFF10493D1B1E09A7149D353B253C1B6ACC04A2D7C9C0D39F693A7573E853B55846167214C6886928CC844397503418AC414924A2FA37BAF19DD33232F9C9F9DD1AFC78318CF6A37230D9E5CC178179CF", + "9DD7A8EFB207A4271BC08473293BA333543980F66EC095284CC9A36C705637CA39A42AC2D51005D58743BF00BBBEA4620AA897663B41713507BE6637A8A353A1D60E14417A9DA8B35D9471D864BC71A26061612C1A6A4DC08BC9460A1741906D19643D185A504AA3247988156ACC0FF8671E07B3C8D0BA7371046A18B7414CF8AD01E936C10610D6868C7C8B6E2BF5110DB106C81B7B3EE6BF43991050C01BE0CB3EDF349BB92887A1AA6F40D23F36DB1663706926783ABD5A8C5ED84C6138289A45BF85F782BDA86B4F81AEE5D6628591AF594738E6B539630A93FAC133CA406E4766A1A6B4C867EA580D06003579C0F875C88362278E452D349C2CDB070C877446BC18B400957CC04AB7B084B3CE28A3FA6299CB644315C1AD0D691F55B65427CA1828E8A340C5838F49090FA8B47D531081824EDF126315B90278266239B559662C9717A8A92C64293E7CCBBB98A2B3E80E5C845524AA34C7D42F1A1446BB818022142AC6113B3E7289D200698FE05CE67887C6532CD6FA5C1A295F3395572178B2E3C515701A15D40AAF77783697916594235C97FC979652242640011758AA40424821AC46F33CA43C1C5DD31614090C9BE96C7584672EFE810368A71D76403E32424F9E3197D44535EB717E2109653D3CA522A088403156F1975CB6447CA656B27461C8F5D8B77118CD7BB0130A56A3E2689687031DD18A2C99B51CCDF5621B2C684583CED0F25859118C84C9BE253603A8C627C8582FDB4BB81BB693CEA821EFD712B33730D68A0232921D202120BE959401155670F119A3990158D2C5A6EC40157287BF5B70D7699B212665248CB42BD2CC6B02BA15759BC5333A53794E51D033BAB16F59F0A284B92171017FFB00256B6C9F8311188F24B2B26671A4F1C2AAA000826926469B9336D315FD29A4C38A8491F79B1F9C3E9F653E41B0CC52A6756F80CBA4C27D82A370459426C4F5432A5696463B407DF93816711BBB54BE092793976C159856BE92183C3AE1C14A5C9C8A39AC74836752ABB09065831E22948E3929EB00BF561CC57A597530370B04E10458F34E2B7400537C73FA902B02BB13AD98908A793208842ECD27BBA4C22FA7204C8187092B1012F3001D495162FB97A4DF0B5C2B0740230B7FEF2C5D679B2541387377A99E9B3A9650E64C44300897E8961F5B65B0559952603E80105A979BA1B2F26F6103647A1123A7F830FED26139497D77D220345A620812785061334CF002E50439B0B93A803198FBD80B238C9F969C3BCE8781B1F2314AB48933628C2E6301B8FB5105299739D31EDABB5FA8CBBF8C57C764E1B04ED35379A593FB869B7AE37C0EF093A44AC1A75CBB2979776E34C00720B095328F6236664005AE6A2846A1BA7E086B19C52C91358443C395BE7603110EF6A564660009246ED4B800E77250B96C665B9CBD4B74B4154A8B98561CA4395F92D405956223294692662B46D69043353A7923D72B93BC3F1923AF70B9C1772B8AD5078686694C56C746C0378D35732161D50A6E9AC012796A4A24203D0038AA9B573193264A02BC8E41922A556770D6A2C76AC5150C1F27CC3360A384397A118ED58746B4221C84414A386711C093998C705096457FB9098786985450C645184E4A4861C4750BE91C16F9E25E42C9BC2C865FA1181477125C42C727000640ED09AA7FBC75808B0C5E3AB6004A7364D51C66B48E10A42F6B625B5FC07F0C108A15C4547DAC3E10C59F613273D437050845470AB02A95FAAADCA3B336AA96334A1C871885B7E3AC73635BDC33BE6564522B9C7D789C459E422A6DA3C333B9A4E29A792C68A6B685088176922E06C42D0C030A30C229B69945E32D7500A1754A605BF3C5F0E50C9188C7A3786926151451187CB2931F8EBB06F3D8985D8C871B02987D47CAD7C84F423CC252D2340BF90C6A58241B57220E78A20CE82D28703C0C0619095057278B128289396E08BC876B3E171A2CD231BF5BEA9042418D9B42C75E2A90416A2259EC43D105119E47695001C70E766AFB798421A931A05B455B3AA79E034014350CA7D47141F43BF90017D61139DB380D33793954A10332F37784D25AA59A3878E0B99E4CC291B657F8368D1C025217A292FA200A9CBAB8CE832EA9BC974EAA4CEE3B875D12C0BC9B9C57B56A425816D9B14C6A90974F34A78A186903DA0EAE76C0D1A903D83903BA107521096B9BBC2B82268A3D897428968216362017F967866598D8A1559D067FCDA8018A7245ECDB70BF96738EE7873E146D2E9715A6ABBA07413FF9F902A3D966D3C794FAC83D7937034DB0CE645B0CE8040AF9A5A8713503F07154945C0BA8059780557A0A1B8475681FF1B73FEE227091D377782993299C02F5E9A58291A7403C8620A401459BB01643C623590B685BC2FFF28B2806613E2926C8A802B51CB8ED1005ACB255DF5006CE373C83C54E3CE15977BC8C8E7515498A3F1B58594A2248B4F450F6879FEE66C214BA4C65D586E1EC0E44D8445DBC8A60755459D1C29D3A25D753C54D721D248102D9B171823232767C5F4CD73EDC3553F2F1BA940096EF154EBB6700F4218CA9405F918996681C59897C868BD56E5483376A89649393B7B6E3BB53C9701BA02278877A53546E6B38008555A81CA91F47E05B40348E2A16CAE03507F66BACEE8741ED1B38704267CD7C29ECF13F9BB072C81A716E89651D575D6FAB5FDEBBC0C9860FFFCAA19399C690B2184EBB8EF4F2A8FFC149B5985C7B3AA0ECF64B13EA38013B5701B49004052DCEC7BF1044C800F86B5CE1317F285673985DEB34588FEC259683C7B08382A877AAFFCCCB06B21CE7839607CC2E7A13B7B5268FD314424740864FC10B5552641FAA410FC633F9030DB1602A8487A664F252F1E1936C647912D8205DA16CFC9A6F89622F3BA4BBEF22343F408C6FB25F90037944E057925C05E7CCBCD02041E1CB9C029B9B125582E4F7B62D3243A5ACB50C50364B27341B9C2E101742CE8927BE7B8933F6027B2145DAAA311FC3C6DE80441DD47092336BD834BD77A2A5974156227ACB24252C0FB35616015D2CC6CC33E9328A49868AB630F1CC14D8530BF0A68DA1D244AD960FDE1A63BB880F5BF67A4D8889D7102851E85D80130B344181A69C23FB34620A9ACA78C124718982940AB57C570CCD7368E3B8BFE47A6ED0F838929BC68E558296FC1E0ED46B9C401F7068B1ECD28626F37779B3C950B914D7447D041C79AA1C72550B08FDB13829D05692406D57DA181E772C2C79329BE81DB20B8807CA460DBC1B68A49E4181CBCBFC1924DA167F9202A777B71E7B794B0B8FF54375FCB4231B648B3AC229CA9C1215168553A6CD1EB9AFCD299C0A96266AE09C06DA5641FB72B15B9F26D79FACE24C26E67A33B28B1A80538AC9BA943A7EE239AB6E3349D65674E9212ECF7762DBD0A23119AF810897FF331970E0667BF07999A531B596B0D4116B24476BDB9757D4B67BFC99A4D3282BF415A544753934552A1C0519A132C84804803CFC2721A62D848A07DED647B0246947D003B5D014C44BBDB4D3BFC068C099364495937224216B6DFB79DC870686E5A5CBBC366268B8CD24A3CF6101C2D6537C57252155AAE570BBCD958D25D51BE95B545A24AD29D6355C34A81E758DE7E671B932A9ABA80987E63781DB367CC0CED8987C688428416625A97C77DD3251726716D375B0FFD8836D6A606DFC7A92A727CFD0BD5179A55E6206BF83983E756BC150B9BEF52D127226A106C8076B91EBA32B4384224F970FF0393936E89AA04B864ED73572194A628A053D526F5FEB580C4270F1226D1EE907B047791210B3E388B0753970957706F1864FB7EC2A314B812494AD9A3B6F82C567ACAC2DDAD6A05D720D8EE80819CB47819A21B64C0633644CF230BAD92920B451711C286A04BBAE34E1B55E737F487B37D33274B591272F562E271A884854AC3D2C35E2949937E0550D10854B4613FED929972A240DE08A2BBC76FDFCBD13F91C3F074EA6FB814289739FFB464D7CB9CAD280DB16B35C23548D7C0C44C76541B701F99AAC04BB1743B467788A836DB96E3D530CC3929FC424705A8632F1B437DC45B86B3328B15B1CD862455D991E14699537EB94E766B509D1CEBFE411E3D14B92099A803250F5466397B2439BFA159BE250E7D14A72E4CFCCD24AA4998EC775A8E031B9691980F50A0407CA221DCBC3880C3A25A54164D6913D016B63D27B66434BEA65C80F3A753C57318EF98D36A80272A0AA7148C8761170AC97979094AFC5485FFF10493D1B1E09A7149D353B253C1B6ACC04A2D7C9C0D39F693A7573E853B55846167214C6886928CC844397503418AC414924A2FA37BAF19DD33232F9C9F9DD1AFC78318CF6A37230D9E5CC178179CFD2D08189948550B0A7516EAEB161713983097A7D58C144E1853C9ED002913413441DA27BDEAEB1EC1ABD9E2646B05A311109B11DD7EF25E93ABBA1345F106C6C", + "D6659CED5978246739F1DF34E2B87199C7ED98DC02DBA276FEE6B14491F3D958DD59F9108A560B2149D0A31D0723EE21D06FE75AD924A778B2B020D5B3D675591B6C4336B81BC2A5F9A5AE5B0112685C35F3B1404ACC223AB5383E213BEC1BF9514724AFEBE69C8484C6BF287EB6FDA8681CD4552AB2E4E0C30139F435F4057BF9A8844226E4854A8D4ADC08441B71C94CDAA4054104895D096F3F0993C6E0C9FDCDFC0B9ACE1A57441910EA73F0821289DE798FDD3B01682A03E5203215E2DEA2B5766A10D6C8B5308AE9DD2A7D8408363C8802400AF21387BB9CDC850B2E7805808D4DBE3F12275B3A980DE2401B62F6CFE0C9659A9D185CE11C5EDFBAB0390B58533E46480F2055F1FDA93B6BFF0A9BF8954C72324D64D9C24FCD2B13199610E6892FE4C436A84B615A99E141895E47480B9135513C2EACC1F45881255C0FC495FA4988A02A2B62696554822D637C9AD14F4032A38E30A751B2974CA618959BD8F6C71FC35CE024D7FACECFF8511145DF9643E84774092D6BD78A3F216DFDE5E46EA1F7DED9AA7D5BBA46033ABB16D41A0FCE60E51C2CEB99448FD5B56C0AB256852AD4C223EEDD23A94312EB3168A958A143B7770A326F00D268CCA97D232A6B6C566501243F80C9BF97E9FB24AF76191D122E60B75986A32D483974724FAF5E9D4D909895E4C01C8848D7D5EED3F506F16AC1E9706C6BB3CAC5F097CAE88383BB6D9CE1FCC91E011907F7292462DA88254450D23D2AEF3EFE4C3A28C59BF9596A22A54BC5CC6BA66BC3299043D90CC0362ED4712CA9623BBC1A22BB9AF195200F60E5BF16898F48BA60681A5F2F2702413A71892AD488C689AA9D98BB013EDF091D900EAF2E6F08645A5DCD72A885F3261CB02087039D65922B650E80EC937C2E071F8E039DC61CF9C9F0EA27355B7302622A82395C4B087EAD072A27EC276C0B19976B0AA2AD76C885B8CF7759AEFFCA82CA0576DE8F86264E3F566237A436516CDA35E4F0CCB12143245138A8A0C3CBB75A330FF5EA7FD83D0BE5FA09B8C95150F4BDD2406D2155E26F082841FACCA531C0572C1F969AEF1BF22DE8C742687913BC52E880B231C097AEB92992008371DB707BCC2C912F08F196D4F36DDE0686809EE8BAB0B3AD64CA61EA8993BDB89339AAF8EA2278820FD584ED3FB2B267DC0625BA6431FE82D54AEB21EE801500CA883BA94E51550B4CE2C7BCB534586388944B5561524E0C2435330C03C735DB5A823CA05A85C38EE2FEE5833A6EA9B0331F0906CE90CC3D18A24C9E1BC0417795F9A0D1BC5F1AE1B92B58D442DEBD054ED900F24D46EDA9A5ED49C8016440343B0530D9A1148FA561EA179A55E2A8534C7F9E65C58A37FA5093626C2934C4D971CA71BCCEE4967624B58721D8422DA54F5EBF23B645B49220F66803C09C3BB726D48B2FA508CE044F8C9695F8E7A947B14863F4C3F4C7AC8964AFCB834205A06E6217E676B0D475666A4FF2579884F7B27906A420BC29D1E80035E6B12A868E90EC144B1A7C36C1EB57547920951BE4D47D7237A479BC96CADD2BBDF9AF5434DAD9527F0D13B3BB9D8C6A29318CBA882B81D621F4AE9A2FFBFF7F16986EF5A2514AB744BF92E9B55BF913AD0EE590E2065D9953BB003B35A5B8EB1B9AD65593B441DA63F206C444CE3C4A9F33B1F90EC115E7604557BDB42A5CD33CF7C54E081BC2D092229B22261F9B2FBA0EEFB354DB0D1DF54CF2AB9D747AA3BE86B2C4C3FB1A998341490C35E39D143966267EB5ACDC7DAD71AC2D72C53FF14D38A88E6014406D961A69A82DEF636D95F0A0771AC249C7D9E275C4D8C50CEB336E684D08453CD52BE6613E03909A4E7B172BB7B8B2F9458FB1526187FC80EAB53819D09F10A9BADB097C69BFA9B23EB099DC6E6167601228A18065D92F6CBDCF56A0DCB195964F33BB94EEFFAF3C986665DDE54F876BFFF0D066A648E6EEE3407BA7464D7425C212DAF9A92A1504310BC71000A64FCA459D56DBA81B6360856600CA1EC765061EC35F20D78E69160F31953B32079D0F7E6A426B19F3D6CFFE9E08672E712D76BE09F0A9F74F942247CF6D2CC24B3464D120325F405AAE7456A8F5D13FE3182FFC93F8EC64B9DB4505091F471927C5B505F79C8DC6CE3F668869CFA8A1BBD76ADB98477877EBF644A69D393782E6B06F2AE427F5EB08F2AE7DDF0202B6F080EB14F2BF97953E450CABC922D9", + "AA820E3C3D1E72BF7A93B10D856780E853FCF098870A62C7DF07B8F0BAD93555" ); yield return new ( MLKemAlgorithm.MLKem1024, - "C1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7", - "13E490ADD15409C73E2BC9B0496A9513FC89D3857C5E0A9661E8B8CDA9B3B0B81778863940AA9A970123BE3ACF07E97BCC397BF9E6C245029ED518BA64A20AA1E8154C3C736A1C17B43770AE695C38E96B6EE270DE3C81228497E74206272124E3112FCF7ABE938B9B8B51B874FC4362066559C6AA41E462F912026726377BF6681431BCC5D6AE9567230A5681E3192AA6586031DA7A41891C0FE61F9041C475D33570F2AEBFE03910C43B28E549E5C1C21BE2146352CAE4A66FF8D9ABD769963D93BB6F7C8E1856B2DB4311468645C3D8A824720D2FB93CA547A0A7BB15DB3B6A6E04367837AA378734A88064E033C9B8295099F336B1A80493FB8129F79640D263E943B6E535AAD7459F657A59A1CB12B19C8121F15310357D9125825D745F3C6B788DCA96F743C0F7DA9C033A6F2C8A9F998277F1B053756166DB866D2C2AC427E85AF361C7DED10D292A5F876C8B228A655871BA227C1A56B98B8B962F233C3A570A98A01600296249E64ABD84C70CFE91050CBA61D3588406E7A7A1CB199D07862D65C9F617433D173E557B385FD86EB3A642C75494E2273FC7B904E66B4E58B97CD82549A4635070224E5E039D76E7CC055872A356529E39A27E160D64570B5C92A9B9513A6670A227F7C9CEB3450F55B2AC50C1155AA1611A5DED59A069F43B9E3A9E4DC70F4D1164C830AD7BAB499491115D9201518B60CE8175F43327F8756E3DE2B34F653FC4933381F64EF9926D30686FF981C860A517040BB9EE140D0B541FFCE389F1F51DBB4CB51AC393DFEA5B6A55500D3C305EF88112985E623205516807AB1664CC8ABCC107583B8BB3E2E585F95B89AEDB45E5278C4D7B0960355307453E4A954B51B0A6E817CC16AB1D47839095798E6F7C53EB9BBDFDD0B5005C244774BF3AFA35810226E5D4C7C194C285CB8BD6DC2800963D2C1C7204B43B7290ABE6C17AED934D50F538AEDA48F28527DEF27C331B9F122C2941B884C2BC3E950C1A15A6AD5CD17623339C09872FB899245FB18EF879C5B53602C9436A15B79324753A9090851C3184F699CF75E0648AE1849E401385706521219DAFC8326CE8968BBCA21FC059E62963A532A096DA91457427C2A65B45C22E06038429B52B5F732C87C053E2AB38E67457F3EB967F402B7E0762AE4507AFE1196F22AE9E6797BE959D69DBA5B6FA6493E84EE8B3807FBABAD2C07180D8877F17CA92E08E0356CDCCFA9B9ED6268D19196E0BBD14693BFE72510F6151A9407338128449D3806C230B617525E9E01290AA21EB8BC8C70AC60028492A79B354407F5B8C786239368800C1B2D412DC6B14FA9226D1E765BE1780C0C346BCE1147D692A0BF195A1A2CACB75C1076B59222B214F682B8DEB7B7F51BF7BD9C775AA5474C4CE52963C546170B5539DC39C6ECB963D9C260D7253CF99F404DD49BFB7B4C3A90726B3692704910CFFA2AB8AE528D2A944E80735FE25917F960FC9D1014AAC200380A3591638ECBB44F5975708F584C0C392F2A20D2D1B698706853E28117C9139F303AF622286BE0176AB91812C962BA1C311AA9AA8F334C387424177EA6564EB318F832A68C11DA2418FB4BB6B74F1736955CAFE3170CB467F19F5CBEA7A8CC93692A3673CCD8450AA85860AA04BD4EB8008E63EDAE0A32C4413B3242AA9EB1E94371D8A02BA93173BBC93840EC2347560AED85A97D3DBBF0D7CA052635C794B824BD66798E01E70929FB1CBB81E865E0819749B92063EA99DED733751024A143339ACBA3BC9B065A19006E28B522D2A10B22B325E723E6804A2F19270C5744B1754A13B2128F1C3BE87D3968C8213E5B55442E6749FB21C49396B0B427C030A3D9F397525D8B8953B945C132E5B506B5130708A55C41D8B9F7C9B0781D5340D029E538378640A1A57340DE7697A8CD37B58C64FBD7518F55AA276650C94B40C71B435FC83927740222BA32BD8947B7FE3277D9301B1524ECB735EA358AB6BC41682728DA25B70D1AA2E35A4606BA27351A54C88353A3D455651C3118AA578C4B19C557A6DC1B290AB2C97CCF96665C10FBB67A935477168E0185ACC1155A0132011C4F2523732373BD5425AFA7C061BC66C7883803039296C989224A0BDE9BC4B8B6698EABC6C40A10A842C697B3873D84BBCE048B69DC705E6A7BB6C813BC1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7D26129D71267870D23C3FCBA53A325F5F4EFDD0818753D68930C0C2797E74DD2FA9550567AC47E70FE9D84F482BDAB1A8CC149AA7889E4ABF8ED76F68D624DE6", - "E80B4738ACEB3ED9BAC18CFE16151B91FB34814594369002C4A92232409BBAB226E302551C01CAE01ED07759FE5EB79FB3CA262C9B55475179A789E92FAA7812858082281405659D163A593F61F15F07EC945941E0DC2AA3DE1EE12EF9041933BF9BBA268C447E81541BACBBECE207AF25199CD8A6E4C2480ACCED8DF80F8748C6AFB26C55542E73EA0D42E9F01218E78A6F21B19BD4C64B2FFCF510C953AC9E05ECF8114E91878FE6437A296DE8AD37BB4B634382FD76D039C006E3AEFB1E85CF1510D24EFEC428175601E5C78A3583E52134A69A2EE5DDC1B33EA2AF27287EFB843271C73D31F78152D8103136DCB655F483B5F4AF2BCE96FB730855BA929A59A5BBAB7A45732026E6FAD23068A1D8C57AD634E63CC92BF7A3B83B72476B5488172CFE6DEEFC62AC13E33A3C67EF1A360C5E671555B389D884E5B159BB43EEC56D3B1B934F8E6E339C5DF6A53777472557EFFB3A6E0695F09A8161AF7A3374083F1BA16BC17EC5C550CEC84BB00B550864348F82679BA32CB9F174733D0A874F15C39837A5CCD54EEC16D783053369B860F34EA5E339BD48B70F0C7A2E6FBAA8CB3CF4D7F0AAA204CCD5042D8C77E8D73DBBD8DDAE719DA6207C92DB8DCBE258EAD6C67E9AA66AF817B005A83C39BEF8CED728E569293F92310E75D0C75BE298BE201BAADC319FB33CCA65C725CFF71D02D33727B1AE30080C9895D5C5C2AF301FBBDABC3F23047AD6BB4F1C5E41D9935519E091885A3BF4EA3F1794C79AF719698D49AA7786A0554577D90FAB6F86D1ED048E35E1711BB2D597E3D13BE3079C2E8AE931BD15D6E7B2F805A339B1E88257E1EEA7D84FCB5DCA1E4C304139DA752A19C0E01376D94E9223DA8C298A63A60145E2A732001D6596F12156048977FB2A348237C5B82ADE97626A7BAF264768A593B0E908A3836843ED936BB037ED4A41B0F1EACDFE101CD0A7EA18CD3B009AF5ED2DDD450A2FF456373041981C6479A5EEAAF1D4453281C6ACCAC590B7B0A4B8412A2DD2ACCCC321BE10FC369789F21F3A53155F9E493CBA6C9651710F45928217E2345386D6C559CD0CEDDF9C2BE2F500A637F3A3C423D3D832782BC4A871FD8B1E95099B23514505A1527C504683D9E3AE37FCB94C67C5B3C08BDB6A2B17A612258B5B1570AE36D829D62C108B7C5C0E3DFAAEDBC00D49EE43CC4E360C44BC2E5403D0E17B514B3D055C4772EF077AB733DF9052CACD4A2025EF42099D06EECDC3B12086BA38C84B733E793662CB5F4A09AD25C6BB7B0DC51912DB42CBF7CC457B9E85D6EEE03CBA2A1E17DD61BAD8B06694443CBAC0424B83DE4DC153A4FA13011C2D5EE86839AC0BA531E4520F8482E94D92BB14FD54BF218B2731F426F24C6F015633C884F78656E23678AD34D63E67DB6F8F8A1185C3C31632CEFF78F17F6AD923A0BBAA3ADE397D61D35C86D36B3A915F705CAAB1B72D51B5A4771CD47593D73626BCE0B8491951B0E160B7370AD062E7BFAC5C1AC81165C3386B386D181C0C12C05CE332A6687080523A1A493AFA7E106FF9DA419B7A04075FFD4849E6EAFA0DBBEA0ED8140D6CE551268AC6CC161B024601AA012332FE9D02B5AB632B2B2EC5D7665B6580ACE5C819A1A857AF163F5E9CA93370BB5D07C86A7367B5A35029D100A81AD166FDF8B4CF96E9D9B43EDB8AC40846BA5A33C7FD314B0BFA84D89FD5A5397C9B4148499B75F290FECAAA06B88BC48B07994EEF65917CE4F69B72A8E3AE6C8EEE9C6CBA65EDE2493EB77975B67DC8779736F68E6D59BC6618E09B855D9F85E85F5C8B64EFF4B13B0A643540F7685A95F51F5064E34DEA21BDFB7DB6825FAD8614C08CC5CBA89661E1AFA7FBACB992AF7E56EE4758A90ED28261EBBC931920B2765A44043CED4D3758D71A0D6114A25DFAEAE551764A93A536CFBDB27A0BE464BFE978830B6EF0AD9C962582576515A1345436407E9625200D57F5DB90254D40D3EF006A5361D907ED473BDFD2371769F42DBADFA52201D63431BC6AD691D755CEA136B1524D3D19B833DD9295B327CDEDBA4D6B8EE5CFBEBB49166FF85C2A40CAE024051C23433A3C62000BD3AFE9FF51518547000A78D31B08D51803A8AD4FF04DF7AFE15152D3FAD850D7742ADE9ABE1C1216AC0BAE559194026DBD1D7217D8B76212E4C5462B9EF29A6976FF216D98E3F3EAEF7BE8AB432E1B6CCEEC83CD46D621EE4CD532", - "458A7BB577EFB1BD795037BD062CD5C90766A8885ED8E8EFF24FB166EB8BC0E7" + "34214407C69920DBA6D13C5F0C604B5C3A14706485289A59FA13347D2954BF93C6D9A8422BEA42AE03B52C93B34E4B38F2A8802D9C097DE0018A0CB3455332897559772B3DE476518BD9438A8558AD02676C387EBBE696EAEA0CA8F99ECDB3AC426A3F1DF8175D7CBBE8F7019F5C0EFC73C131299A43E3A6BFC02FB481A67DE8AA8BE507CBF60C98712D8F500E86D0B76690922E5B6D191A2A70B09C6DC7AFDB689F20627A96B41C14F687A1580BC245700E719B96F3C1701792E33C62A3AB544D01B2A080844B274BC39B289557658A886AAF029DA770BA6502857F2929B2B60A530CC6FCB247672C85B312B80ACC83DB8A689137BAD832C8CDB55152B54120E16E07A9414D651BC74AC13637B7AEC71E78F6AEF2E45C28CA9FE2BAC911327DAF628312472B2746C9DBDB35A517A3A5F65D0378BAAA4B6CEDA515FD868AE96665F624A83F0AB36825C9ED0323A825AAD64BBCB479972967C1C5ACAA7B82C2DF629974C3643FDB417321A22BD4B87DE264CD63BBF5C3C1DC6B2F202CB2680239C7135CC2D2A50398615790BEC8D556F310C72363AAD22003037706AF2A0944151868AC623348508717AF8FA65B4C01521D769F5181B820C67BA7210D62F9AB48D111FBA402E8E40D984CCD817196BD9148AE5A751751B093B1622E8A5CCDCCBB7879C4D70A01CC84267CF5463667226911B06B548448B54A44959941B6C744F1308F029AD786210877619DDC45A92A5B9989A7B939185FCA1E2715CC29B59E2D2591A8BC51D51A214CBC28DDF249F81846516410E63788C24B1B3BFA4BD7C08D38A3202DC05EA24570DBB64A9053550A495B009B2BDB142B64829CB46CAE77770C5AE40149365B70A9C65A77C354673428D42F15704E2F33255C06887B844EBB6B1AC4C3A013FC7B84A396EC9270F21BBC54201C1785B2B779442454515AA0787FF942DD8A33261B3163E13FFD9242964626C4EA38178695C3D59577C1B69899CCFAB5CAD5BA8BBCBB0F0222C552B695EDC701956874622354979C0F1FD02CEE957487B16A6B73BACF59599C84A0371573576B9557D61D702C0541B5CD3C0008867328ACC94792704439377FF516581E0BA0CC9C64E3C0C9350858FE466405633C3CF515617B5E22572202BCA4854B0EE66876342B2F0F87397305A4B8BC0D62BBB4DC821C79B232654455E1F4AE163155440297B75B01ED11A5AB0A268AF54FBB8C6F0DD190CBB78A85CB055DAC95AA893700C504CE7431CCD7331A251D0BFC0C2DA5BC5DF6407AD41E7610C165255452AC9DF79108AD48A7825ACB0A1B6A9133C02AC173458243528278411392C10A83B82744E826B444005D1A61AAC8F829CEDC4419DCB740F07FC7068FE513A00B1684847501D94411BDD715BB004AAB084BAA5B369FBC4D5289B17E3079E362944A498DB9A5544CC23BAB662C28390102BAAC6EE3C1010C8D18865C1548C18852A22D52325D752EDBB65DA1E61C62F95BB2633A9F1275693CB8F3A8CCC5D7425EC50389725C934B5A1AA3324646247C3255AC452C917B54CAE39EABBBC26A0143457957D7098F1C47B089C76D402A04B4001E4A4078C0F0CAEE6CC2E92960FF39BE90C14C45E25CBE948BB68B35EA406EFC462757D5A7D229BE9B5924087A7FDB042D4DB7962F359A4FBA01C60079157ACCE06B9779F2AF475B1E56C3A144B123EBD2B128A00CA10242748057E4B7976B68B12F4482BAE48665F3B0E9AB06AC8431B074BA790A388AEB12E2495E147B2C68A961B080B81C74B546E62D0D9355AC4C59717662DC74B620A75C7FC24B3A932AAED2BE1A4A74F250118508636BC0327455285876167ACA92C57683BB868AEAD9B789986B9BC4BE3F2C0B63C39C1A62223DE202C01A62B48172C3C461E90065138B8EDBB24A640216F5EC8D3E617F4951A09C25263E60C4BCA69688D7491CF394AEDCC814B746946396416B29A2A2C683BA1DD6E9606114BC3E0C9E0BB5A020A1771A2B7CED7A1CDFE6B4E264BE6126A30A27A4351659A827C84EDC1877023F66660AA4229B613C658D450928D10721D596A3B7A4BBCA221CA206F5250DA82B2CFF0B79BE386456746A98F37544EB67D8B291B0E862EEA231A6D048D7A737201111080979BED52BE8FCCE9BEB993D5B49EAE1B70C45593BD1381E4267BEA05B6ABD9865A8046FC716F9E7C14D6933048E1419D0D16C27E38D1D8908FF60CF2E", + "08265D9C0A335CEB667057C49418C445940F883A6ED314979AF08E0D9AC291F879D5B87220AA3AA752BFCDFA1D7D232179365862B351ADFA26C516C05946BDAA81914E26A2E10C453FCC29265B95BE3415F0524DC44A1855FAA33C0438B041B8D6769D62237EDFB45E4A208974806365E636C7A0AE683C363B27CDA9835A7DD911382A581FA6B227470B946611F30ABF00EA8648A9116BD522ABD6404AA8BA56C5B2E4A9B99AA4799E0B5B3C686724BC645AB4AFD72715CA5BBF3AB7210C24C41A273663489F0FE38CD426463EF54C1C8A84D6CB80B918879185AD169B5A023968CCF28ED46AA50579B1FD18CD08E210420B47E4F1B742D5A305D5C90D96528AB9758928BFE501244D63AA5B30A5FEA90A682064190139B0B23F8EE7B27D5794733C184A498B006C3B29166241FAA32A731317DC1D5B17A2F3B8CE6DD21794C86A11223E4C4316CFFB5C40A87F169C8E43D0C22AA76C08C657DFD7BF26777B47EAA93DA66CD1B669B2AB92ECBB0494709B6AC463B1843B2E4784A4C7C0CBF835CE263C2E6C921F429E8EDB8267F64E389463FA7A982FD994EA190DBD243C363B58F7B6554F862FAA6565F20174F3E27548453B146434C2F3615F0A09DEBB2A29E2C0C05856014A799950CFB1AB6E52960F7E35696ED267C0F9572AA973E020BD052B1CE1075820559F7F15A746AC6CF4F70885873F172673343127006B17CF97A7C72410D814A13B54842B1C5EF8707FDC8383054B7597C36007D442D87C1595298BFE654BEB453923CA1120B60E7F426006E4380240CD3F07663837B117A676602703AF034999600F82E1B0D8DB2AF5C80F69721804F1AB0B5940E7F781E97316AC211093C6229EE0467D77A3DFF77547D81BB758A3EDD6AC3B5081B52AC5FCD160EC22AE28703D3F7C06ACB25288D3CCCB65C440C0C04215488D731D8B705D67106D9AA19491C080B2CCC713FC598B5012134558D6E08AE45425B5210DA9F1068A7863EBE3A72F08BB93A7A7F87511B483AF22CA691149574C752FA86C3F4ACC1FF0688FD939BFFA865AD37470AD657A9A45423670205BE69D886A1AE8C9B311337D3461A28A5C5F5A66060EBC85BF464839316E1BEBA123F7CC4CE11F314A8A62D35678B2C875980CCF9260C6AB55DF0C8E8E2C2BD29768012249BB9A4750D250C8C84622F6657FAA481A7451897405C560CD7AC63C3FF0AA17154155732BBF653D7BBC055F127F043BC41226AE4E14BD5433BED32CBC05B82222245ADDB454BDE2BE67C1465E8765B865C058A5A12CE3B25FBA3CC451B04007898367B56C516F2BD9C28F56A23C3A50FC9826F6084EDCE3294F299A50498A244431515349D6809CBD7264EDC639E9DA492CA487030024D933183C803444C39094B5B882801A87D1AF9E59AC394A711E7A40F2FABC0C3B74E72551F450497F21849F5820A70246676ACEB3AA9848C980129574C86BB8BCF496218113E4372A950327F4A77A52C648171B36D4EACA63CA0B3C196F7FAA0B7AB982BE3126419899EC2618EA04A36C452555674D2AE214D20A11837A8FC80B8BF1A3050CE559CBA35FB6B0C8942761B57A0765536E44219955E33D26F32FF07B6DD9E11251695CEED594D388440A5950A55583B760363B6C17622A5DBE97A41E8177373056E999643173C453B445E3A1438C39AE21A36268B4CD71E3351AEB3AE0451A764274E9A24120635F84E345AAA2403A7885CEAB56E2795D56C29291500A09FB55B5F938095392B3D3125C556E7DEC08E295234B784C9B7A54C87C6A1810097494A2CDDA5848483C7DC120AC787C7B8C1DB2DA39EBD7509C02A7D9CC644129586FB66E4E6C2F8219A6489C02FB4B7A2A04B2427113039A24F35C8B97EA3860051A05F4132F6699D5777CBCE9253AC1B085E306189575E853CEED6423566943CA193414C47D3A55A05EC37ED38C4225EA35B9F17C5DB84D4045CC4C520C84E3338331CDB0E10251E2679ADABC8F41BAA1DA8A1908BEB2544740B92693BAA1B5FC6498280B694414A341284447C4D0606167B44B04AB5E5CCC45DEE39EFBB105D2DA41A5B4AEC247CC863B4BA91AC74BE745F6E9568515CFE266945F715E0CE5B2A595B514F532527581D83BA0E1A76D800BC237550A84CAC77B24A05E5BA148282187067ABA0B7BD98A4B34214407C69920DBA6D13C5F0C604B5C3A14706485289A59FA13347D2954BF93C6D9A8422BEA42AE03B52C93B34E4B38F2A8802D9C097DE0018A0CB3455332897559772B3DE476518BD9438A8558AD02676C387EBBE696EAEA0CA8F99ECDB3AC426A3F1DF8175D7CBBE8F7019F5C0EFC73C131299A43E3A6BFC02FB481A67DE8AA8BE507CBF60C98712D8F500E86D0B76690922E5B6D191A2A70B09C6DC7AFDB689F20627A96B41C14F687A1580BC245700E719B96F3C1701792E33C62A3AB544D01B2A080844B274BC39B289557658A886AAF029DA770BA6502857F2929B2B60A530CC6FCB247672C85B312B80ACC83DB8A689137BAD832C8CDB55152B54120E16E07A9414D651BC74AC13637B7AEC71E78F6AEF2E45C28CA9FE2BAC911327DAF628312472B2746C9DBDB35A517A3A5F65D0378BAAA4B6CEDA515FD868AE96665F624A83F0AB36825C9ED0323A825AAD64BBCB479972967C1C5ACAA7B82C2DF629974C3643FDB417321A22BD4B87DE264CD63BBF5C3C1DC6B2F202CB2680239C7135CC2D2A50398615790BEC8D556F310C72363AAD22003037706AF2A0944151868AC623348508717AF8FA65B4C01521D769F5181B820C67BA7210D62F9AB48D111FBA402E8E40D984CCD817196BD9148AE5A751751B093B1622E8A5CCDCCBB7879C4D70A01CC84267CF5463667226911B06B548448B54A44959941B6C744F1308F029AD786210877619DDC45A92A5B9989A7B939185FCA1E2715CC29B59E2D2591A8BC51D51A214CBC28DDF249F81846516410E63788C24B1B3BFA4BD7C08D38A3202DC05EA24570DBB64A9053550A495B009B2BDB142B64829CB46CAE77770C5AE40149365B70A9C65A77C354673428D42F15704E2F33255C06887B844EBB6B1AC4C3A013FC7B84A396EC9270F21BBC54201C1785B2B779442454515AA0787FF942DD8A33261B3163E13FFD9242964626C4EA38178695C3D59577C1B69899CCFAB5CAD5BA8BBCBB0F0222C552B695EDC701956874622354979C0F1FD02CEE957487B16A6B73BACF59599C84A0371573576B9557D61D702C0541B5CD3C0008867328ACC94792704439377FF516581E0BA0CC9C64E3C0C9350858FE466405633C3CF515617B5E22572202BCA4854B0EE66876342B2F0F87397305A4B8BC0D62BBB4DC821C79B232654455E1F4AE163155440297B75B01ED11A5AB0A268AF54FBB8C6F0DD190CBB78A85CB055DAC95AA893700C504CE7431CCD7331A251D0BFC0C2DA5BC5DF6407AD41E7610C165255452AC9DF79108AD48A7825ACB0A1B6A9133C02AC173458243528278411392C10A83B82744E826B444005D1A61AAC8F829CEDC4419DCB740F07FC7068FE513A00B1684847501D94411BDD715BB004AAB084BAA5B369FBC4D5289B17E3079E362944A498DB9A5544CC23BAB662C28390102BAAC6EE3C1010C8D18865C1548C18852A22D52325D752EDBB65DA1E61C62F95BB2633A9F1275693CB8F3A8CCC5D7425EC50389725C934B5A1AA3324646247C3255AC452C917B54CAE39EABBBC26A0143457957D7098F1C47B089C76D402A04B4001E4A4078C0F0CAEE6CC2E92960FF39BE90C14C45E25CBE948BB68B35EA406EFC462757D5A7D229BE9B5924087A7FDB042D4DB7962F359A4FBA01C60079157ACCE06B9779F2AF475B1E56C3A144B123EBD2B128A00CA10242748057E4B7976B68B12F4482BAE48665F3B0E9AB06AC8431B074BA790A388AEB12E2495E147B2C68A961B080B81C74B546E62D0D9355AC4C59717662DC74B620A75C7FC24B3A932AAED2BE1A4A74F250118508636BC0327455285876167ACA92C57683BB868AEAD9B789986B9BC4BE3F2C0B63C39C1A62223DE202C01A62B48172C3C461E90065138B8EDBB24A640216F5EC8D3E617F4951A09C25263E60C4BCA69688D7491CF394AEDCC814B746946396416B29A2A2C683BA1DD6E9606114BC3E0C9E0BB5A020A1771A2B7CED7A1CDFE6B4E264BE6126A30A27A4351659A827C84EDC1877023F66660AA4229B613C658D450928D10721D596A3B7A4BBCA221CA206F5250DA82B2CFF0B79BE386456746A98F37544EB67D8B291B0E862EEA231A6D048D7A737201111080979BED52BE8FCCE9BEB993D5B49EAE1B70C45593BD1381E4267BEA05B6ABD9865A8046FC716F9E7C14D6933048E1419D0D16C27E38D1D8908FF60CF2E2F8DEA3AE8653BCB9935DF628B9A6072360BB5CAC4E5971670CAF4E19AD3D7758AAC6671A36120298D71E16ABB51CABA153F9FF216BD99165F51467DD36703DD", + "3EE66A1955100C98B610E6A4A18A9EEB852427CBEC4AE60539AC8553AB512D70281FE78763837C36D991B4391E67B299864CE3D10DCE75F4831DEF03E4C34C2B8EF7054DAA12C8DE0E61E67325FAC1CDBAA3108635F620F203BC0424F605E435CBC879803628DB6F4B7033097FCCA11E1AE5398C805C7C6B2F19B1ED00601F4F66B72BDB41047532225C3FAF52A64FC0D095BABAA4FA60740D96C0E0C17BBAE6B53447BDF35DEBB477E0A5FF14370F3A53441AC1E7A9B33CEC34FF41961D0C48AD86B0FAB158228A0CCA2E10639761AD8A7172AAF4469FC35FAEAD99CE8A564CB8588C4A9A177A22684FC90B0B90A0EE5F40565E2CC557092BA6770E698C2709D00E1D593F97D80CFD586BF003F2FBB1098C20D209E150389A686A00D481F976F8F38515E31C43A94936F56C4E424FF283B09E50462A550F1619DFB56EE1622DEAE4D867813DA2B057FE08A3BBEB95635186EBD38CC644327B9AD4114F88D1CD8FAE5623DE5BE95650BF56310FF9AE99032A0968EBF61B3EB51ECB3A307FDDEC5BFB4D977A82DB57FF7B2EF680124A51A6B9F9650AA0D2D64D65DF7D2FA0D10E7B6260DAAA9FEBE23975F3C8D80A90F429F64CE08593183BDA4560B81F0C14882FBD4EAD6B74E716CA829B282E516170A71A50279FE8F77656819186E2F0E4BB87CE237DD8959EA5114098480C0183616D23503C4E2775B5133A773351417AA8EF3B7176D16B2BAED0F11716C098F88DA261596436AE6DB4A8A02D0858EE0DD7B8399947C084CBA0177633BCE810557ADCEA9FB33B767E859AE90435634EA45165C190DCBC073BAA44CF653E7A1F28C9ECDCE96A5234C46A61CFEFF9032214FF5B95FAC29175F5E341218A32FE3E9580F48F38A0A73173502AF970164617EF8D8BFE74375E2E370A96C1202F7C57D91AA0392E84165BFF96DBBEC4938503C7FF072226E171DA842C09259F04D2BB7BFE9B8C575D7348756D808F66C7BA7349ECB01D771C035B49EFA010E4ED3461D33191FD66BCDF5B703D87B0EA284AA5B6C3376ABB8474410ADDC2451C2869914626087DFCCFCB934CAC02125E380F2C164089BD7965A23CC362CC5B91B8BEDB4D5DBDB704211DCAB31A2DD3C9AC507A28B6C4341E35746CB857F60B42FE80DE5DFE3B98BC9E5AF2269A4E411FB87B5BE6CCFCA65B05605A0AED7BD320A7C63C073308EAACFA0C9EF41B23FC76905C1DE314CF333D48A7D31BEB2B6077F75BA41FA1BE8066B099EB68BA343C2C7388E834BAA13300F1B732558B9F2A61B565459BF3EA4EB012F081F6EF5293E3F02F1B00582B2F1FB1F9F7618C1D712D39CBB391AEB20A17DBE1F7EF6D1124FAF725BE1B62BDDC3C213A88A882CEDE31E89F91E9728CD0040832592AA148FCF74474382DCE42C07D6884C4F806F1D67A1048B4450EC80D129375FB54115F27800E157F998E8C72D6E94C114A23A78DABAE57DDF13A478050F01406471B94CDBEB68F993CEDFCAF946F50968210E08BF3F28A6D5686B4421F0B463CA41BA6FB76045BB406B6A53111B85107278AC03B6090457953F3B28E7E31B9815AF5CF25C708ABB577A7A590CCE4CCCE086F6D29344A6B8144505AFE76275FD074916DAC0ED888213D99C8904BFFACC546F6222B3D9F7ECC811253389E814170AA372E90FC90BDFD52502BBD46237B7DBE9327EC23EC71A510D1DE47CDAC0EFC8C0F0F9DA84C6C3E03C075467C3CA1ACDDF997C940A21D2DF516CA8275580351826936454D35CA0EFAE86E6CFEE66F97035592D567E63B176D7A7C96B3881381E5F5195ABA9658C935A7FF2CB2E7CC7F2F9C1C60A4CD1C8EDFA55F6ED1FECCCA088BCC75D7C5AC42FEF26DDE63E3CF5B00409EE80CAD5AB8544757D2F1CF59207451FD8366509B620D5C14ADB500BB54B0BB8EFBA5BA4A47AA1CF7C588EAD5939BAA825D1C45519BB15935CB901177770D1C4A6D1CE11DF7037452D95C64F744690B9831985EE63FD73C73EE20EABBF349798F267ACA6A852D3FA6B108E774106D48F465D3A739554E8BEFE9BC2CE1BDFB90755482DBA8461F72F7BE1180927DD7FD8D8DCBB23AC488FF171524C0948302F81D542FEC3451E056B14D81D81EE2300133B2616823A99E42E34FE319C644D8976EA832A73951FF6528EC42B0B6960F88C384A0B85D3030ABC5FC38DF8F0D2D1E77811E8E6A4B14E8B6DF3BDE605E7B241525D5E8A5A0CF93", + "33B4D18F7CBAE3FB6D79D39C4728C543BAB7D40B6BF20637FB27619FAD4DE514" ); yield return new ( MLKemAlgorithm.MLKem1024, - "C1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7", - "13E490ADD15409C73E2BC9B0496A9513FC89D3857C5E0A9661E8B8CDA9B3B0B81778863940AA9A970123BE3ACF07E97BCC397BF9E6C245029ED518BA64A20AA1E8154C3C736A1C17B43770AE695C38E96B6EE270DE3C81228497E74206272124E3112FCF7ABE938B9B8B51B874FC4362066559C6AA41E462F912026726377BF6681431BCC5D6AE9567230A5681E3192AA6586031DA7A41891C0FE61F9041C475D33570F2AEBFE03910C43B28E549E5C1C21BE2146352CAE4A66FF8D9ABD769963D93BB6F7C8E1856B2DB4311468645C3D8A824720D2FB93CA547A0A7BB15DB3B6A6E04367837AA378734A88064E033C9B8295099F336B1A80493FB8129F79640D263E943B6E535AAD7459F657A59A1CB12B19C8121F15310357D9125825D745F3C6B788DCA96F743C0F7DA9C033A6F2C8A9F998277F1B053756166DB866D2C2AC427E85AF361C7DED10D292A5F876C8B228A655871BA227C1A56B98B8B962F233C3A570A98A01600296249E64ABD84C70CFE91050CBA61D3588406E7A7A1CB199D07862D65C9F617433D173E557B385FD86EB3A642C75494E2273FC7B904E66B4E58B97CD82549A4635070224E5E039D76E7CC055872A356529E39A27E160D64570B5C92A9B9513A6670A227F7C9CEB3450F55B2AC50C1155AA1611A5DED59A069F43B9E3A9E4DC70F4D1164C830AD7BAB499491115D9201518B60CE8175F43327F8756E3DE2B34F653FC4933381F64EF9926D30686FF981C860A517040BB9EE140D0B541FFCE389F1F51DBB4CB51AC393DFEA5B6A55500D3C305EF88112985E623205516807AB1664CC8ABCC107583B8BB3E2E585F95B89AEDB45E5278C4D7B0960355307453E4A954B51B0A6E817CC16AB1D47839095798E6F7C53EB9BBDFDD0B5005C244774BF3AFA35810226E5D4C7C194C285CB8BD6DC2800963D2C1C7204B43B7290ABE6C17AED934D50F538AEDA48F28527DEF27C331B9F122C2941B884C2BC3E950C1A15A6AD5CD17623339C09872FB899245FB18EF879C5B53602C9436A15B79324753A9090851C3184F699CF75E0648AE1849E401385706521219DAFC8326CE8968BBCA21FC059E62963A532A096DA91457427C2A65B45C22E06038429B52B5F732C87C053E2AB38E67457F3EB967F402B7E0762AE4507AFE1196F22AE9E6797BE959D69DBA5B6FA6493E84EE8B3807FBABAD2C07180D8877F17CA92E08E0356CDCCFA9B9ED6268D19196E0BBD14693BFE72510F6151A9407338128449D3806C230B617525E9E01290AA21EB8BC8C70AC60028492A79B354407F5B8C786239368800C1B2D412DC6B14FA9226D1E765BE1780C0C346BCE1147D692A0BF195A1A2CACB75C1076B59222B214F682B8DEB7B7F51BF7BD9C775AA5474C4CE52963C546170B5539DC39C6ECB963D9C260D7253CF99F404DD49BFB7B4C3A90726B3692704910CFFA2AB8AE528D2A944E80735FE25917F960FC9D1014AAC200380A3591638ECBB44F5975708F584C0C392F2A20D2D1B698706853E28117C9139F303AF622286BE0176AB91812C962BA1C311AA9AA8F334C387424177EA6564EB318F832A68C11DA2418FB4BB6B74F1736955CAFE3170CB467F19F5CBEA7A8CC93692A3673CCD8450AA85860AA04BD4EB8008E63EDAE0A32C4413B3242AA9EB1E94371D8A02BA93173BBC93840EC2347560AED85A97D3DBBF0D7CA052635C794B824BD66798E01E70929FB1CBB81E865E0819749B92063EA99DED733751024A143339ACBA3BC9B065A19006E28B522D2A10B22B325E723E6804A2F19270C5744B1754A13B2128F1C3BE87D3968C8213E5B55442E6749FB21C49396B0B427C030A3D9F397525D8B8953B945C132E5B506B5130708A55C41D8B9F7C9B0781D5340D029E538378640A1A57340DE7697A8CD37B58C64FBD7518F55AA276650C94B40C71B435FC83927740222BA32BD8947B7FE3277D9301B1524ECB735EA358AB6BC41682728DA25B70D1AA2E35A4606BA27351A54C88353A3D455651C3118AA578C4B19C557A6DC1B290AB2C97CCF96665C10FBB67A935477168E0185ACC1155A0132011C4F2523732373BD5425AFA7C061BC66C7883803039296C989224A0BDE9BC4B8B6698EABC6C40A10A842C697B3873D84BBCE048B69DC705E6A7BB6C813BC1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7D26129D71267870D23C3FCBA53A325F5F4EFDD0818753D68930C0C2797E74DD2FA9550567AC47E70FE9D84F482BDAB1A8CC149AA7889E4ABF8ED76F68D624DE6", - "40C229A23E71E694C2154594D972A719206BDB236B79C2401E7D67C80BCBB4EDAE122352AB5CCD69047FA196C24C9E00D7E9A7F803F64C0B6E48BB60977AA532FC399E70E457347607C4CF143AF741EC437F3F35A90656E581D592A9913D8B59A05D156DA4CD8A4F47F7522E90F68C49B0EEA77102111C343ACBA4108F32BD40E9276528D59084AFE7E8D13051C909C11BF5A4950BDA966AE5A0DD9370DDD4B7C5AE5DF67A388B4B5B4C6E988515A1C734FD6E4EF14A933320F43A1DCF45A94D8636C5B664D00260C5EA4A149600BEDCA87F6D84A8208EA08569F0BD18D9A273710147F83C1E6F932CE732BF83BE24DCB1A9B7DEB176049665E28FEF039DBC1A94FC8285635D6C5C7EA905632A0448F3083C3DE9477755552657DF46DA79B3BABBCBD14B74E74CD9F86A0971E4881D778FCBF6E7FE2D69F662CA956AF2B71340AF14866336809E223160651DA19878107AA511FDD21ECA681C942ABCE8D8B73BD115036E56AB9773FE48829D92922AB686D4A32A74AD62A131F5062CCDD45774A686677AC42598A07B416BCCA695A10D79271CFBCAD2F8DE73674912E3C0C77FFEC70A4A9EE37462FE96D0C90FB90CBAAF00B2909AA8604B21501376C20CA7DDABAD95792EFC4F0689D9A10125EB002959824E1DD99EAE87BD0A2895768EAD9835DA4BEF9371228166EE433CCB4D3CC45D57B28FB06DD27BF19986C1902BA229E49EF89DB36EF7BBFB3C542E00B9AC908734FE05865783D2A492005CE9B6E0825F4A2C9F4C2990AD59B51FB6D664FE34ABB33DF8A23A614CD735747265D18B93936F80D47A01AA04FE841BD466825201BA91E8432900F46FF16E3D1D6DF3240C8D59FDB87F8402A7216B2151360FC109E77D8AA624C757640C010633C7F0334F98142A411A98ED20EC986F4ABBA76D58A4AA5DE534B26E01B30421EB2823990DDD87177F869B3EB97EB3B1AFCCF3D77A00E1B94BB13B952E68475010FD13ECE8846690807DEF4B7191B9902E44E6C35639EC521EFB56BCB72D72C5E1C3BBA47258D64FD9E098EB6BD30E7C7D7A92F3DA526A05FC15983D5D79A47F749792D8B125BC61250CDE347EA4BF69EDE22F4FDA412476CA261F01E08E1BFECE625E687B6C2828D07B9CF51F46BE6B58E010A2EBDAD09F43254AD0F221E263703B60513398439FD8025AAB3B40A959786B86599E48DDDF35AF8C4C5B9AFC0C8FF4E084DFECAA7EB738BDF499323262EA0BB8A6319777ABFD9666EBEAB7060EB3DEDEFE0C8379C15D7B2EF6F5ACAFEFC6D575737C085BE884BF01AA5B7F3F275DFD39971C627EC56FFDC78D62D4CF8F52CE9399F7F4F5D8AB9F134F041B894520A277E272C2D5A0D7DAB09DBF81EE358F85A6470F42BC1DCDEC1FE87D6A13C58579C6507FD8D494FEC91CA089F4CFD90A8DD439262027103476CB54838A06A3BB4390713653D4DDF903D93748F95A260BF65CB9802B1423598170FFB4F24FEEBF53E974A85C6F0DF4E9191B07B7C8FE780F0A0F1058BEC9257FE32915D0E6A1992E895CFE097E7877BA12C1627683CAB2D974A7033954732DFDC69B455CA3F927273C294AE8B48813640CF691D68CC86DE9CF1D56B79C7B26860039161719894CDA2FB26147A90E60FCF0C7C0D516CFEE7F9719A8A36BECB2B8BDAD33CA4A6CCF5B39342DF89229FD8404C2D5C25A9B771B1B9A3BA588E47838AE1D9EB8392294F561BE9EE83F89FEB3D48882C882C08552B64FC95D5A7084736F9C7A0C9448853E47DDD8819C0927642CF49FE88E8DA02B0528B32CA5BC9DC85B558A4821B1D7DB6E779CBD2D78787DA23DE5EE5ED2A965D5DCAA1491A663E640736096BF703CCB2FD42342937101C536DC74D31D8E51D376AD20ADB51DF34E0B69CF4783BC1D2AA592B2C6AFABE7D9394FD7EF2A3C60F22B68ED4F31CE57F376205E6F0292D1BB5CEFE52ED30CE526EF14382F8BE594A7EBB401FAE8DE7980E8AB83D90503B9228DDBD4198917B77F507C96B7CC58A073ECA250D33FF55071A633F99C57F3ADB2ADE11199104D80A98B36A509406DC77AD8766A4432992D5921CE05617E24F7CA025D03D451FD9F8BA8FBAB41AB6A801B53F1B593031E596C465180923AF867AE30C02A127DC76E9D60F3CA7C24DC536DB2C2767D2560D2C35609224ABA7952F9B620562C7E954A94258CAE9A13E71DAD2A204395E024E4C13D30129B7CA676990176E3", - "AFBE52F2DD9F6575ECB165CFAD5F5646D89C1B8DB398A1C51CBD6A532D0D46F5" + "B5947AC486A788C55C95633FFFC33923A051F883B68E144C1392896D065D748406C4AB71C09102730C6BAAECCB0D249CA0935A9C936233B27F941A4F1DA291B56B02629B2FF7094595962AA9BA4172578F650750A11305C7C390837A5C48A5B892962C30A38DCF1947E343CDE8E314F5816AE6E70125C2BB400BC426617954AA4437799E6EBA8605843776A4755A313C88F176B924C71FC993AFF95A0AA266813169540064AF119BC26A9074D3B6B874113A56044AE76E644A0AC7E4045A8965A4A1103011865DC153D008833C665A5B4A490068C02E979E8A4B18A43BA283B8B13A190585CC5D2F2BC9423BC1C51C0EC6344A8A675D646874E5D01B994A52834208876A2F3B2C09BB0B4D4401956208D0DB5275146305CC851BBAC31C40B5C59406251715A50C6BAAFD21A7E80C4AA90BC6708C491C3161BDB955289172E3249F81402FF9C53BBBF3A1C1C7A678F508B9789A290943FEAC2B093A3733874DA8BB00E5F81B3BF30B216B915D78A689C726CC9629B0A83987275FF065923B7060E94161E42A46D194679D6790ADA04759405D8D0A5442B1194F364969EC321BA4907AB442225A5393A3CCCD020E63184091D53DB0A21C55D6086A45939DB4A4F23C9382B2A91068662B818EB7924013141DF94947492B2BA4771D490AC210C2805445C40D5B526452349FC984C67B73D013AD3869C7570C7A160030979B6E0A293B5CB2082924865263762FB16B3F3BBE482B53DA585AB325A3E6B130D7AC337EA7AFB6502B8AB61DB9E7BCE3343708FA62F9B8C3C306AC4811A0B1B4BE853577D3382F86534192B22EFC8B6A41498670067B8D2A4A6B627610272E3C6488FB198EDD1C7300E46CA18C652F8799C2CB2D7424C1540C81A12463B16895D66B4268E03ECDDC0EF648C12434A8B8D8C580ACCD43BC979060CC14BC40514266723B7B7284A5BDB6B6F1994CD1938958B61147FB1856967EDB406D9137525FFC198D520E8706185484707CAA82B6A0A1D7C40AD0AB8198F8AFD530A398042606ECBDC380988B554B1E2C0DD4490E3DC6310F20C0D7B866A4D3439604CF695361A0002A9DE95818E50A1D614472A43559A167ACA2C75DEB0AE7082BD76373CA697E538B26B5E36BE69C6905DB5902A60EC3FA846D3A7ADEAB415766176F91316E3CCE0A03B29CBA0A1E93387299B4DD9C6281628944914B6C388046EB5199618FAC9034F38283B111CB9964CBD1A071734140BE6B4256E280418867357111D477A14313502C8719B8584385050E2735AE8E6371EF96C135F5A89FA44D71706E15441ED5C316098CB00F37174586418D340BCCF8731F33A22008C059D7289A42B4278C5499FB60AFFA58B30B7D28D72EE0433E8D6A9E5D8612271399DA7522E84187104317A13BC58DB2CB768059CEC5A0C8586A0FE0867A691F5EDAA65BC19B0A6C7F6E8247B455ADE334184A287FE8E6C9F62516400B86D1528BD13C419E80B8367CAAA7F6961B729FFA64A244D0BA2EBAAC5C291B0B745073569E6A85316B0823F73C782A59964116CEEDA9758B800CFDF78544A312E898A7019A00C36C0B4E6576F3657363DB4461504CAB162D520073D511AB1E6A49C7D2B13AE60B5DF2014B2712C872311F57CF19548A42B65951782625A68A1DAC5A70049FCCD9822A971259D255F5BA3D1C66C18758C797107771559DBC729DFAE95548E8CB95EA18E2940FB2F191A8E191B515B9C7EB775E0B4AA0E745C73A49D03389FBCC95AC769AF0BA3792B92EC42BB320B53BD18CC15A86A97DA4C8C9A339F849712975B040D283853B753831C43F13B89655363D86535AE38A1B51001FEB0CD1B05938B287217232817B33A5908CA92CBE688516E23B452D2328ED4A95112ACB8A18A8E6440A16B2CC643A9391C38C521A73783B631DD1A15E4823CB6BB7ACD12E25113266C873CE5774451605D949B75C5A38D6BA275EE6CE84619BD6CB10F4964249F60C9C062A7A52BC15A188494C132DBC36A657363117C852E113733CC208089298D5A3211904E7AC1C501A51720985DD20CD50BB07F3CC933444A79205C05FD22D1A533CFBB11D75039C17820F167A8417D029ED1BA46F086A4E39C9BEE7084D71B636F3B62AFAA64F32A0EA519CABB3519867107EA9829A245800F2A8A7278CF2E52001C63AA8E872961966FD63FF1C1284A2EC73E91DD388D5112F94F0778187C118A2B197", + "CBC478372B69E289C9BDD753A9A636F490B4732564D70A15D169A4961950D618210A156DB9F89F41D230668619114C92EF53AC54CB5424984CC8ABBB6E6BAF6304A67BA997E819208194CAC23B53CEB2BB41873352326FC2B4A405471B43A646E4A1924734151EE85A68C4B65C396666985205222D212B452BA3ADACF8454A42858D4690ED4A3ABC19A9F381B21A551CE4804664F644111151444C156CA1A87C6C0F9E6281F22ABB93AB32EFC77996302DA905386BA362EC709A130A1811EC8B88C4CC7D168AC0F2A24C5276BEFC1E3766CA27EA3134A55FD3B3C87CFA197F406FE14864DC628227E40A8A10B89482C7F90B008DC011523881992482F7AB2C35952BE82A0E3741CD637003FC66811F944C24207FC0684F2A39B0A8EC73EF3A3FFEB6BD4512B27362AEE5371D9107295534BFF4DC461351097B8B877114CF9C9933E27CA51F842EB81A8EA981597FB0C2EA17288B75734294302355CAF75BC9F093727DB629ADF87DEE8AA54BCC97940652A8449F5FFC2A65F031624A239B250256A7468884600B270C444362BF3569DC49146C7072E9636F4A7639626ACF3CECB796025B51959078115ABB9B8DCC469DA4C00978AC5DE418A0ADFA0FC8281324DB8472C44EC6A053A86B5EB8430BC6ABBDC8EA5099F000F24B62571C996506C3DEE1339E6CB6F968072829A99AD60733898800200E32AA5CE2F926990C1B120C3A149814C03B76759275FDB631B293A5D51A0BE2CC8B8AC513A9B950B185526A35CFDF44077B138F8FA86D5E935F0CE548041A516963C47DF6CB8A9A1D065AAD6C48CA2CC1B206375A2001071F699CE1E505C13BB589D150FE43433812B3812C50AD9956332793CC972C89DC7F376C95DBFB53F4490375B947C8E362B872327CB46F14524D65503B53E6219E3998B7F59F0259C8BA121A0AB51533389504E5227D89BF3DC71DD2BC2E105269F66111B0F15D46647DBBA27A90D2A182089B06C65FE24B5D275759215270233A74E4C455676A2A7E8C51F5170208122EB5C9714C3C23F0B88BC522B533294058CB82FB3C3272E17B3E28133EC2698E941932D66B057798E80517922016C31649328551F32A938E791650B4C34C54A5C2B295BFC67F371C84F46197890B1510BC0DB5AB17710642255C8980DAC599105A0FF848E08C629FD8935372C17AAC8469492CA27970B5C603E9191A8A172EA8A9993C5990C7129059E0248A1C178687900A797AC83406B9F95213E606CA3A8880C3273F960447BC00CA14473FF4A4E637AA0F638BD2EA502F04BA71D12AD3E8445730733F983F9BD17FF7E77B82CBB4E4FBA4766A779E50BF53AA0C9F1986CF1090331177E84A367F455081EA1E2BC96650D81B9C09B8055074F364CF7BB62A78CBC92F80A00D10CBFCA093CC57C3DA963025BC819C2CB09D33331A2B2612658E813875C6D33984B6806269B5167B7864D56CD1255B05122E17C1CB687C3164010B5ED81C7F803085469DB5B3CC0AB431CD28378A5B9BB411280627A9638C1D57F2675A6815D5934FF93B9FD347AC50EBC8D1DB723ADC9C0781033E805B663004C3143D859411AD2C23D9089248A7B000472B2D08988F61056D038272BB2215D05ABB459F0137BEDC916511D3C3A3694C3F2068F2508B44F5857D814522528AFD01CD5A26C58A3118841A80C8D649D6AAA64842676CE3C9E1072299A948C5B4C807370C9AC24E4113927D584F8EA9227ADAB5DD651A9FD237E124B9DB3B2A08315F22A954FD46B374847C465CB7DDA931BB400C66FAB97EC1355B213B03DC74D8193594B4A33F3000B8273A5F8077FCD5299F778305C4A8D0548C4EC50D31FB0CB1758BDB7B572C5913A1D4ADA94A8925D089B7CC38CCC4817CA7894E25012D897EB59276C92B9859569793B93829472FBBD317A8DB928D77C2B9A34CA31B6A3A919F9581050421030FF50D2F970E5E491EE3D9558F5847B0201CD3FA524A7B049126833AF67929CA1B3C4A145C664747A1627E40B3DD6247BD4A6595CB571405907699474D2C63080023E59888A3E5736495C8A75C8E3BFBB35787625323A583E322DA43ABA975B0B468733C6AB5B9D6148AC61245A9C1D2B880425CCDC0EB8BE4D763688B7059D404E0CC7A60FC2881EA38D19AC98A4103EBD7422C91AA1EE516CEE398B5947AC486A788C55C95633FFFC33923A051F883B68E144C1392896D065D748406C4AB71C09102730C6BAAECCB0D249CA0935A9C936233B27F941A4F1DA291B56B02629B2FF7094595962AA9BA4172578F650750A11305C7C390837A5C48A5B892962C30A38DCF1947E343CDE8E314F5816AE6E70125C2BB400BC426617954AA4437799E6EBA8605843776A4755A313C88F176B924C71FC993AFF95A0AA266813169540064AF119BC26A9074D3B6B874113A56044AE76E644A0AC7E4045A8965A4A1103011865DC153D008833C665A5B4A490068C02E979E8A4B18A43BA283B8B13A190585CC5D2F2BC9423BC1C51C0EC6344A8A675D646874E5D01B994A52834208876A2F3B2C09BB0B4D4401956208D0DB5275146305CC851BBAC31C40B5C59406251715A50C6BAAFD21A7E80C4AA90BC6708C491C3161BDB955289172E3249F81402FF9C53BBBF3A1C1C7A678F508B9789A290943FEAC2B093A3733874DA8BB00E5F81B3BF30B216B915D78A689C726CC9629B0A83987275FF065923B7060E94161E42A46D194679D6790ADA04759405D8D0A5442B1194F364969EC321BA4907AB442225A5393A3CCCD020E63184091D53DB0A21C55D6086A45939DB4A4F23C9382B2A91068662B818EB7924013141DF94947492B2BA4771D490AC210C2805445C40D5B526452349FC984C67B73D013AD3869C7570C7A160030979B6E0A293B5CB2082924865263762FB16B3F3BBE482B53DA585AB325A3E6B130D7AC337EA7AFB6502B8AB61DB9E7BCE3343708FA62F9B8C3C306AC4811A0B1B4BE853577D3382F86534192B22EFC8B6A41498670067B8D2A4A6B627610272E3C6488FB198EDD1C7300E46CA18C652F8799C2CB2D7424C1540C81A12463B16895D66B4268E03ECDDC0EF648C12434A8B8D8C580ACCD43BC979060CC14BC40514266723B7B7284A5BDB6B6F1994CD1938958B61147FB1856967EDB406D9137525FFC198D520E8706185484707CAA82B6A0A1D7C40AD0AB8198F8AFD530A398042606ECBDC380988B554B1E2C0DD4490E3DC6310F20C0D7B866A4D3439604CF695361A0002A9DE95818E50A1D614472A43559A167ACA2C75DEB0AE7082BD76373CA697E538B26B5E36BE69C6905DB5902A60EC3FA846D3A7ADEAB415766176F91316E3CCE0A03B29CBA0A1E93387299B4DD9C6281628944914B6C388046EB5199618FAC9034F38283B111CB9964CBD1A071734140BE6B4256E280418867357111D477A14313502C8719B8584385050E2735AE8E6371EF96C135F5A89FA44D71706E15441ED5C316098CB00F37174586418D340BCCF8731F33A22008C059D7289A42B4278C5499FB60AFFA58B30B7D28D72EE0433E8D6A9E5D8612271399DA7522E84187104317A13BC58DB2CB768059CEC5A0C8586A0FE0867A691F5EDAA65BC19B0A6C7F6E8247B455ADE334184A287FE8E6C9F62516400B86D1528BD13C419E80B8367CAAA7F6961B729FFA64A244D0BA2EBAAC5C291B0B745073569E6A85316B0823F73C782A59964116CEEDA9758B800CFDF78544A312E898A7019A00C36C0B4E6576F3657363DB4461504CAB162D520073D511AB1E6A49C7D2B13AE60B5DF2014B2712C872311F57CF19548A42B65951782625A68A1DAC5A70049FCCD9822A971259D255F5BA3D1C66C18758C797107771559DBC729DFAE95548E8CB95EA18E2940FB2F191A8E191B515B9C7EB775E0B4AA0E745C73A49D03389FBCC95AC769AF0BA3792B92EC42BB320B53BD18CC15A86A97DA4C8C9A339F849712975B040D283853B753831C43F13B89655363D86535AE38A1B51001FEB0CD1B05938B287217232817B33A5908CA92CBE688516E23B452D2328ED4A95112ACB8A18A8E6440A16B2CC643A9391C38C521A73783B631DD1A15E4823CB6BB7ACD12E25113266C873CE5774451605D949B75C5A38D6BA275EE6CE84619BD6CB10F4964249F60C9C062A7A52BC15A188494C132DBC36A657363117C852E113733CC208089298D5A3211904E7AC1C501A51720985DD20CD50BB07F3CC933444A79205C05FD22D1A533CFBB11D75039C17820F167A8417D029ED1BA46F086A4E39C9BEE7084D71B636F3B62AFAA64F32A0EA519CABB3519867107EA9829A245800F2A8A7278CF2E52001C63AA8E872961966FD63FF1C1284A2EC73E91DD388D5112F94F0778187C118A2B197BEA6091E1C84EC506C2DBA85F06A3C883B351B68C1F88DD22A5B8D715A31FA076D75A0A5B9CF72985A33022D52E1E6E48F9BEE0BF8BFFB7CA184579815CF8198", + "879871CFD21BB57F46B6E96AF4ED88C8A5BCC36DE10D9ECFF4C43A37366092ECCA6298379E97EA3BDA1C7E2ECAD560DCD56D1C9F1E5808888D72E78CE3968F7BCD883B73AF503A4967ED7BB2158B74ADEACB327120603E8DC121C51401D61971ED85BB1EAE35A0584C9FB7BE6FBB357F36BCBD14C3979C759D4C05DCD122CE431078D067A371CB41B54A42BFB9B74556E778B4BEBFEDCF8685D848EE1A22EA758CAD402E1FD8E33D8F3726849006113F08B33A51BE65C9094EA3D1FB52E1E71BABA047F0A114DC50626689440F8303BF1A9CF1DED1C6451492D11A76F6BD438477960AB7FF2CC0673B38BA04C69973E881030CC41DFD994CFFC4CA86E0E7CE7817EB100D2637BA1DC4D54531D2AD989519401D7F776B2EB5F16430F361D93D91E1D70F376E1AE319BFABCD5785485462F39EA65D0C49E856CD7A1FA3A6143C38DDF47754717085040C1F64F6C38310549E64944B500070A478BBE6228B7AD282D408C5C759DEC7CE78FE2FFD4B721382465FF1C033C7103143922EC00FD7D2A65DDA8A1DC77E7FBC3DBC2366734085BCA80305B6BFEC5D439E4517778EAD5416A78B852816CBA245EC9BF58641BFD29A9C54FD23A37FF3F767F6B6DC4A9A63F30F9B198CF8BEAD29BF319C01096DC506EA53C21B5E8688BC4C5FC75D5D3AA3AC29C98D5C56EA8C31E90A746C6CCCF729FA8D65376D53A469D1D279861256C96233E47413F3FAC263AF542FF6CA0B82DAA2FB9362692E8BF7C135EB0709022B58513B93AE33F254D7D19667DCA97F3F015EE2D96E64C89D2F45432DDE0708533096BB6EC2E1C8F06376A86F8DA121351DAB44B3B226731520F1A7E709755F3B531CDA072B110FAB7B1D148C13113BD0457AD77CD7FADF74A437A393AFA3C93AA66E0A0A76C0019C0FCEAAB85641EC7AA05A847AFBE74F01DC686D48291E69F98DE6A1EAF56F3452C4F70D62298CC234C5F700BBE190951DADA8DBF725CB44F50394A0D3717778E0DCE7FD72FE26685236D04FC8E9EEB0EA90365D181AE90B7D0A7560DD0B00E1BD55F9F4FCEF3AB393A2AE2A13345588CA6CBAF9A30FA58E3725844F38980D689D1495D159ED5A9C4F557A728E016B87816F40CD22789784859F1FDC39FA30BA72D25B1A14E74AE35F6D52F05745E92EF64ED980F3655473B5CE84491E791A9490CD995493E9E79D9F2EAD20FD204EB67218786161D5F7E5090523FA861817377F013A131A51B3DB0FCC6A845D340E86C7B686A47EE7503A552E0FB0100A6C3DA1CFED6F8EAE04A67C479415649560289C2010B223A107A27DA2F0546EFDE378FD5503912034F6ABDBBC966A47F28A9FFBE7FFDCDB2EDFA19F4639E2FF9C1F4E448F94A8A246AAA17EA9E641E194F53AC24EE125DDF34C759DF5B057423551D3CFB9A1D7B803306E1187CD50E81B1CC4B2AAD0D753CC6319A53DA37AFD47066AA8BDE900632FD7AAB9D93B67A6589DDD14FA7B048CF5022EA51516F9D258671BF578D2E2ECBE5D46BCC165C19ACD3D17E1C923DE1F926E56DD433D861CA64D1F9F622595C42DA1A9880192125308B9A0182C068F218B8E266EEC3AA506D5D85782D6394A9A40F10C3F55B5BE3E13C6FB0B7F5BABD078632C7689F4A49A523CD1B5792F0D5BFF8CB4ABF559220788E560DBBA3C30606EAD7F11B77B5C596CAAEEB28EEEB3C6B92B077C7688229B4394F7F297F1D084BB20D600075727BCB41741580F6FFB832CAC1A91558FA6BE5BC30052AFAAB00399B67897F8208F3FD4D7D8CCDEE652612BFC8CAF4D8C9D9DA35205F599317B35E5BC41070F4E228AA1C3294EC7A2911E02190F2B6697AD05D71208794003B414C96F671350C9DB52842F20E36372646F58B02E0517035157E1C389EAA2801AA8F3B749FE6C98051EC218247071EDE5903C55627424BD4AD546135BA7BD013AA38EA8490C0CE849CB2C5F38F11306894D64419E1B3DC4E2B6B267BF10875224D7EAA7F01DB4A02CCA953282178CB1FADDBB889869BD5CA9A188BE9C01303545E11AFC47B304B175FAB76AEC5091E6C6F5C65BC90B9DC7C6F853285CE436C2AC703928D41B08BFC7B89FC4EF2C39570877A7D7E25E762CCCD09E79DD16EBBD1A50C9021931F9D84153080E8EFCA7E2EC9A8E0CA7344DB6EA1C776F996F65C232F0E6C0F0D612E40C3873456385282080D6F4DEFAE7B82C75B6826A8A9AA68E1983F7D9FEA5CF", + "BDEF9A36C2799E4D58AFDC0509C15023398BEE0D27C1D3C9829475041B52FA1D" ); yield return new ( MLKemAlgorithm.MLKem1024, - "C1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7", - "13E490ADD15409C73E2BC9B0496A9513FC89D3857C5E0A9661E8B8CDA9B3B0B81778863940AA9A970123BE3ACF07E97BCC397BF9E6C245029ED518BA64A20AA1E8154C3C736A1C17B43770AE695C38E96B6EE270DE3C81228497E74206272124E3112FCF7ABE938B9B8B51B874FC4362066559C6AA41E462F912026726377BF6681431BCC5D6AE9567230A5681E3192AA6586031DA7A41891C0FE61F9041C475D33570F2AEBFE03910C43B28E549E5C1C21BE2146352CAE4A66FF8D9ABD769963D93BB6F7C8E1856B2DB4311468645C3D8A824720D2FB93CA547A0A7BB15DB3B6A6E04367837AA378734A88064E033C9B8295099F336B1A80493FB8129F79640D263E943B6E535AAD7459F657A59A1CB12B19C8121F15310357D9125825D745F3C6B788DCA96F743C0F7DA9C033A6F2C8A9F998277F1B053756166DB866D2C2AC427E85AF361C7DED10D292A5F876C8B228A655871BA227C1A56B98B8B962F233C3A570A98A01600296249E64ABD84C70CFE91050CBA61D3588406E7A7A1CB199D07862D65C9F617433D173E557B385FD86EB3A642C75494E2273FC7B904E66B4E58B97CD82549A4635070224E5E039D76E7CC055872A356529E39A27E160D64570B5C92A9B9513A6670A227F7C9CEB3450F55B2AC50C1155AA1611A5DED59A069F43B9E3A9E4DC70F4D1164C830AD7BAB499491115D9201518B60CE8175F43327F8756E3DE2B34F653FC4933381F64EF9926D30686FF981C860A517040BB9EE140D0B541FFCE389F1F51DBB4CB51AC393DFEA5B6A55500D3C305EF88112985E623205516807AB1664CC8ABCC107583B8BB3E2E585F95B89AEDB45E5278C4D7B0960355307453E4A954B51B0A6E817CC16AB1D47839095798E6F7C53EB9BBDFDD0B5005C244774BF3AFA35810226E5D4C7C194C285CB8BD6DC2800963D2C1C7204B43B7290ABE6C17AED934D50F538AEDA48F28527DEF27C331B9F122C2941B884C2BC3E950C1A15A6AD5CD17623339C09872FB899245FB18EF879C5B53602C9436A15B79324753A9090851C3184F699CF75E0648AE1849E401385706521219DAFC8326CE8968BBCA21FC059E62963A532A096DA91457427C2A65B45C22E06038429B52B5F732C87C053E2AB38E67457F3EB967F402B7E0762AE4507AFE1196F22AE9E6797BE959D69DBA5B6FA6493E84EE8B3807FBABAD2C07180D8877F17CA92E08E0356CDCCFA9B9ED6268D19196E0BBD14693BFE72510F6151A9407338128449D3806C230B617525E9E01290AA21EB8BC8C70AC60028492A79B354407F5B8C786239368800C1B2D412DC6B14FA9226D1E765BE1780C0C346BCE1147D692A0BF195A1A2CACB75C1076B59222B214F682B8DEB7B7F51BF7BD9C775AA5474C4CE52963C546170B5539DC39C6ECB963D9C260D7253CF99F404DD49BFB7B4C3A90726B3692704910CFFA2AB8AE528D2A944E80735FE25917F960FC9D1014AAC200380A3591638ECBB44F5975708F584C0C392F2A20D2D1B698706853E28117C9139F303AF622286BE0176AB91812C962BA1C311AA9AA8F334C387424177EA6564EB318F832A68C11DA2418FB4BB6B74F1736955CAFE3170CB467F19F5CBEA7A8CC93692A3673CCD8450AA85860AA04BD4EB8008E63EDAE0A32C4413B3242AA9EB1E94371D8A02BA93173BBC93840EC2347560AED85A97D3DBBF0D7CA052635C794B824BD66798E01E70929FB1CBB81E865E0819749B92063EA99DED733751024A143339ACBA3BC9B065A19006E28B522D2A10B22B325E723E6804A2F19270C5744B1754A13B2128F1C3BE87D3968C8213E5B55442E6749FB21C49396B0B427C030A3D9F397525D8B8953B945C132E5B506B5130708A55C41D8B9F7C9B0781D5340D029E538378640A1A57340DE7697A8CD37B58C64FBD7518F55AA276650C94B40C71B435FC83927740222BA32BD8947B7FE3277D9301B1524ECB735EA358AB6BC41682728DA25B70D1AA2E35A4606BA27351A54C88353A3D455651C3118AA578C4B19C557A6DC1B290AB2C97CCF96665C10FBB67A935477168E0185ACC1155A0132011C4F2523732373BD5425AFA7C061BC66C7883803039296C989224A0BDE9BC4B8B6698EABC6C40A10A842C697B3873D84BBCE048B69DC705E6A7BB6C813BC1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7D26129D71267870D23C3FCBA53A325F5F4EFDD0818753D68930C0C2797E74DD2FA9550567AC47E70FE9D84F482BDAB1A8CC149AA7889E4ABF8ED76F68D624DE6", - "9523B02541D5005CF145D86EA3A697313FCD491D30DC16E0913F518444DE77A78BD70B2B0E5B155DC83CA7C0EB250BC6B4EE649022FFAD6A7EF7ECFE5D48C10DF6FAAABED91CF12830AF3E8B12FE4EE4D8E60D70729CDB32AC8617E1FA95D21419FDDF5FC16F72FC97D083C198220FA2C1351E6D2D6FE68C2B21087A629BE2C7060CDF002531A28E4DB769A592C3E65420B5BD53DE0431A961B9E52A9FC53CD8DACA088444C97E710282AA880DC7275362CEEAF2AB57BBD6D1DCAC1C84176563BD2E36EF5832A0CDA96ADDFC7FF8CC385D1ACAC69242A23BCAE7A1791DC3E4D114B8D4843B587CFCE504996F362AB5D48F171D28507F5B606DD72A038BBEC5D5DA13FFB3E9BEFDF1B821F2FEA3DDA7408A0261598DFBFD0FFF4E60401241C9A85FC2B321229C3D38A13A9FAC868026B0FCFEB55B7D143268EAC680C4B86F5807771BDB33560A1808808B186DC2AA9F72206590FD15B149FEFC6E6FA6FE8CD286D6DC6F71B2AC44D008A8817CE7F12C4BFF9A4DF9F4224D85BA32D16C3E8FB3A17AD3D4F4AF081AE31C2B6856B72225265A41CB374BAAB6D41726FAAE615E0F875F0996BF0893E7ED27C434F3EE36F24197069ED2BCD683F7995C204064A13E35459CE5987D38165A2E1B83DF82D2C7A2E4887B11F89D91A63714F4FBE1F92D1CF212F6D1DD6340301E66BFE2301DE8266BEF53B2F50D001FB05833E46E55859C7EA95E8D18EC11917CD02A17C0A8551E5606E5BBC038047136401A8EDB6C63CAE400B03F4F38DEACE95B7A046EE9641D7C1AB15EBA9F6E6CB067194C7EC6A16A9D8CCCBC182F68FC862CB5B92CA3BB817261247A0F9690930AFEE80272F11F774C556FF3B69D5C2BAD61057FB4483A470D51F332CD279EAD27B335C7188B8DE176E06284172D511CC3872F29193D157F0DB74D5C7AD28AE23132F0928983E7CE21CF2318332F5676C38B01D912BDC7592DC667F218C6785C91CCF0FE61791E80C5C02E3ED16897ABF0F44401F296CDBB29DC6E8FEAF2CA27CDBDBF4297148B260E64AA3121295D1BA38646C5FC614510B73B067798C479214B847799AA39DF423CC11AC8E7C5990840FC488946DF08C20A8B95E7356E2BF83EA45F61F4DF34F2593177D6A6FC5D1240CF6C96F873391D7BAFC3D65FA106049CAC0D97E7B1B93E3AFCE3DA5C71A48260A7114753C0ACDF18A9E945A25E0B3EC7E765AB95BDB9F41E1D2E9E928BAE1B287D954A489BA289135F2E12D79D3EC2D3E92C62AA2B94CE23AFF987CD70764702732E8DE36880A60AE0B12EA6CA974ABF4734120425E3FF3A313373AECDF1F07B523400763BA26F85CEF1C24DF96A3161D5CF4E50D0D9278DA25DA99D267B1F635504DEB2816194698D5F92056ED4F535B5EA3BDF6765DB131B93BEBC00020980E9E282BCD8528BB973E9A1B62548C645228428496AE50CA8875EDF0321C7D3E67B46109B49C1780C0A702E99FDCCABEDF2DA22F6AC2CA7612283C4CF9D24A5A1173C1387DCDE0CEB4D18D34FE4220B0A6BF333432B064F9B5E2E8D259119063FC12A169D1A8EFAD064603AF0C3C66B44BA8760085DFB89434F5FD32DE121226719A014BE785680E5A26E7C9E76F028B027CF030C430A47FCA785F1585F6F04C98792DAE168CE7B40CF27E5E7E11B6171E441D71A371105CDF9EE857F9393D8F6C86A163CA5B67EDB2BE2E26C01369149E13520781896D580834CAAB024F212C6CAD02FFF6D4843437FB851674EA00AC199E0C06410183B6FFE771A28D23B7035ED78912DC1D17F79D1A705627A3069AAB7089D4152EC1E2E3EE1EDD97F185C4214691B71FACEC1264E1EBD911DD2CF015911CEDC13462786023CE96C82288336BB7AA3D138B94EFAE190A69647C1C8143212B5B0C6B3DED79D9EC3042FCCCE7CF6C6214152E08B784DF321F7E3F633E3F6AE3CCDA5F72B37C287673B73F25CFEE7AF6CA242307B09A1486841CF56949F3E1087D619D1FECB08C9647F15B256C21DBF4E23587437D6C68BDD3B5479D9DDB22D532D44E388D27981C9121FE914ADAEA5063927D78C6EEB3878828DFDE4B3E7065F63272F162601CB458D644177B8BD3CEDA62049E85E28A0154816B9C9719F77ADB5C329578ED5768FEEC8C40160A89BA0319D1CBECDD974547A31AFF3397AD3037D9836C97F02D9615A0D61C4FA34369494129CF1D72B0E38B9169987635081EBD4391699", - "CA17438D4B82B0CBE1007EDF321C1D128DC9BE1AB1D1E7A82E61413AD321B31C" + "02043AE218AF1092A508077B6CC43EADDA1C508289CA850D8DE984672587E74743B9422C3CC21998E94BA98756C34A6536989F5255C98253981B710452456217CAC68294410EAC7F463B3316C5B701E5AC79590C9D260BE3AC67534A7E89CA3F96107D3D935DD5039A429B1F0D00C9072C623E554C94C688489B0D551311CE35379394CCAD552B59276B7FF831FB2C33B5443D29E82AD052C806952584C5BDCA3C2CE871441A80AB3BB994C9FCBA502A957D3B66668A43C1E5AD48F5677823311E4117DDA822E3E775EF0165C9277084743D89912F622CAC63438375E7412F9AAE2914B7FF2B38887BA03BEB56FDF18CF4C0486EDB00353636E6F44F6D4A4E4FAC097BE141A6FAB0A773872B747F32C51D9DE257021A36F358BA6377877322820BB497C8077535360AFF6C6460B71D913C77110987D04B1B36815A231AA62866205A0C4DFCEBA5C44797BE40A8427C842FB091BAABA8F62930FCCB73506810929939904105A62A46E7B2C0A09C73C0CA8D18F6C7DB7B20A67C6C0263B54FF07A0620C998F5CF8519ABA855085705C05109CBF653A919E47140168729926AF51C37FA195060B9525C900A80B55E850598E2B5120539105E60424DB93DD0B281BF59CD627984564A48AA61CC9EFBB98AC9342C042BAE6AA49494816CC1B2E2A5A4D250A92EDB9593754CF9792C8187997C6C5DBD957BC44BAD6D21A3A3D97C16A47B677B50116313081481DFD209D7A2B63DD011F0058E4F3824F08C003E76486301C97A63522CB783C49B62FF54C746CB9DC8DCB7F7E83D6E4B88E1450A2332379A0999F5E0B93DCBA630C4A724468F61A44A627C4A99BB5B95F1603171C0703980C2607F246A2C2DB7BAD66CA27C016E1806CCC79B826054BA0F363DD0A77EAB499EF6924CE384A072CB55BE166EBD60BF680B59773597A0B8B255230911C50F160798BC0980CB7393876038F69C3358B44AD3356FF380A70193B7D10C990683CF62FC2E7EB176C2E4C365B1559CE72B03214B34DB183DBC9431AB3D41FA624A01C10E95C687D00CA994658A70CBFF83A60F057202CC61D5C659AAFC7C86021985E380E4E861517583BD71AE7A843A15586E51073FEEE8CB627B0F15130FE182B728020348F5692B84339FA1CCB7D1C85D3868943A0611B122A39AA3FB499784C8C1E3B7A64D2434B0B498320721AD0A0589CC13C89A178CD99105EA819BE904E1AC54DDB47F774CA02A514C513851A9A64E19560F9800C7C835C065D3C6FC59717F262089AACE51842F5E130041FC094D11310A79B872D63F0B58A3D0443008840E5807ABDEA0A5878C5EB0D87EA0330F27DB2470C9C511D56AB43C89E4EA14B46C229E9B2A22906C9FAC533782A632997F198854F2AABE65FCCD877165024358AD4C35B7F778B697B26D89B7F935184103C13B49AA74E7C388390340D77775F84C397645F6E863B28016052586CAF2740C491F4FE16368DB9D89120C7D1481AE647367200400FA4DACF99571E6085F59338D33753763577374C945DC9268998CD9F5BBADA64D67B201AB688DBCB34FC0C1AE05A8370BE00B4B07622A2A97EF661F8A937B5E014264B088374C91D54B72442A4DD50BA0849CA234178B8291A5E4926CAD4A9D9F966744D402CEC274CA84675A77049F822165309212926DE0E6C2D4808C502C94E0AA4851A022C72AA2E467B1298C8121A0C2D6E5BF21837B7FC45357E35580270E6FE9BF2B60553FDA4E838591F1F12DD2C64A6513B78469AEEAB29FAC8504B321855E29715DCA95BAA383B8A1B6A4936DD0524E0B0A9E622881FCB9C7AB882D339CC9DDF1CFF29225A7021FFBB43617771D26109C5B487C2F3558A9A589A8361EC5B4638F5C56BBAA0469F8572BA4BB75F77A4FBCB212D65B5AA28A5B063C8768977678B28D988D8415BF8DD63033183E2D969572779540318909F66C236341C3A1017EE1319CC30815B00543641679A6A2FD3C537B1C3C16DACED7EBACD8C37E36DC420AFC3931346FB3CA0D65787754BCBF2EB4BFD98A8496E9972E747369FB59DAE9B00CEBCDE324684A6989DCE7B5C80099A164832C9778F5C773A9E45D3087733B7A5DE045A9D1463DC8E92A39577018A6BE587C3CEA792C18BB41A6C0A2EB3AB15639C5890C6B7B84B109F04E6EE86A22874AD4457BF85AF2EEA0003CD55F3A10A5B50EC333A6F81576E4E1BD9DEC94D3D2A9E12826", + "1AC53F5F7319C8334FBF791AE9E21F339C1304A9AAA8709141BB7E1603CFB4A4C09834523CA12E5A2797B19406916B57D2309BDB023C1F650CA4CA976E3B09F4848D2D710B44EB646153898A089BC168238D6B4E3FA73FDA088DB3B9A8CCC39A5CAA646DC97FA5DCC2A8C3276B508FE5FB9931D3B6FAF35569543592AB3AEEEB614A9A4AD6B691F22530B3660C1DCA99EBCB498BFC7119A3652E9836D7440E496591C8F7BFD196643DAC4DF0F247E9AA492D23BCF8EA2774E55270919F9A15242D2762A4882F056BC5046C265BAB1031B2004B514FBB389E16C7CF6FF03E41B8674DD4847C56B5D1E9132E78BDEB84B656A9544D1B965FB739EB467810736F3A519FCDA8411BC5805FF89350C56E97BA5B2F3124567087D9C7C2C00C71898445FD15321AA7341AE70623688237931717AAA443441EF7A01DB4E29055C73D8B9526C2204B20309E7CEC507C70A15C6B028628A79735479F5B25AA08AF98615A0F4637A109B4F3C19FF0C135FB172117397FAA03CA3058CF3FF52A0C9859807131FC27C787C31AC38ACB2F470075C9746474816B8C557EB1937DEAB8D1275FB86232CF837CE7A36274435B90070BE53A02B1658E97E66D148191AF60501F1C168D31A456822951289BEC795F9497428F5552F7F95B83CB687149237B0542A8A445146B155DC062B9842A0A44BFB3304D77BC145F0B6B52576FC75AA46EB60E39593BAE35234BC91D80F2488C70670BD001A611399258CBFD247F6CAAB506AB8D64EB54C7230F86D81F25771D61F35331A421C01510A437A22FE642DF9CCC7B31C7A4196576059A83AB9C32538B171A7490011150E1CA628B1CE87AC4C99B7ADD073DDD1517004D77BA4563D55AA168F067C1EA47B673A75FFB664E443C01C1CE340B4756549C84232497279A52A42D53B5AE6F377E063C2EFE6834476739D8972F74A9B4A23A8B864211A83C48378038D5954AB6D64B7191265F0B04910A74C68A4A03EC9768211A0FA5147E20CD4CA97403B634142A62867153422CAF996B967A6B3CCBF646D4B29EA55C1B845B27DEDC65240B846DBA68B36C1C9295587C7C7DEA8610F904AFCC85988A22302CC1B495717C5E661CD8478E05271C6A500DD0543F8AF1541CE25E648B23FDD9CD44174E53858371C4A8E6705E39441148230989C40D034B3764A054A62A50CD2965A3740264C0B9FD47B44BA0224CC44EE7B4257D9A04F5B01499606BC2566F692BB2592950049607009A7734710E15437B7E3A0658D928868112C1A637FDD4089D5BBCB460B939960DF06950B905CA79D3200021533F2B1E65F3B381F512847C1B24FBC141758EE72A35BAEB0648F00798F4A0BAE858C7B71198986C5BAB15C3D04198D18DA17C58294AC9ACC489F224173EE4B6491560EB877C512694A6E90A0F23731DA18A029000B12A2DC0193CC5976365BB4D383BBD36B7A938506019782F40F0839F3C2548E60A07175FDCA336B00A4FC7276D1A72504C222741F0BC8FB94402592018068CBDEA3589715ECCA77D86B7549DE72EBC9BC1FF6AA292B351041075DF6B4EB0A04CD6BB51F968989BA9339298551FE4467BC231312A5D79326BC267B6ED567FA405660910221C0343FBB36350B4CFC923514089408B974DA1F684D659C22769584C375E1465A7265C9208924E117957418254E50572F80AA58678CAB7CA4894F20D82088CF646B5C55C0280817371469C67B09BF67AC6E5BBB0BCEB626A057710D514ACE01298C37749B2A8F04B58D0F65F914A16B5108C7D44921130CE986690B5794414F6BD5C27C03DC96878185CF88415AC3260CF41378AF8A5E4E7C7F6392E7971671A5A3E0C5748741CB10A943F49C062DEC071538ACCF36A71D7D94A22860CF9AA223F6211481369A8CC6FD97C55B690860893B8C766172630A84DABAEE2D38B2F59834ADB7E1F189D42897107C9913EF53211BB5F660B2A63D89630199CD8C241801A87ADD373B00B134FC10162CB3B61B6C284F785650000ADFB60F3432653326ABD10060496A3CE629EE0D301FE1A8B4BA82E6692221E5ACD30351CCE7A6F65B04B1666A808E59C7B2325777C1DF6A0487B266E75280EBB01367EEC05194B5A71AAA28A65CC9687295F6A77B6D3B64BBC66BA11AF7D5CA764D4567FB039EFCC0AF43447A3E1C602043AE218AF1092A508077B6CC43EADDA1C508289CA850D8DE984672587E74743B9422C3CC21998E94BA98756C34A6536989F5255C98253981B710452456217CAC68294410EAC7F463B3316C5B701E5AC79590C9D260BE3AC67534A7E89CA3F96107D3D935DD5039A429B1F0D00C9072C623E554C94C688489B0D551311CE35379394CCAD552B59276B7FF831FB2C33B5443D29E82AD052C806952584C5BDCA3C2CE871441A80AB3BB994C9FCBA502A957D3B66668A43C1E5AD48F5677823311E4117DDA822E3E775EF0165C9277084743D89912F622CAC63438375E7412F9AAE2914B7FF2B38887BA03BEB56FDF18CF4C0486EDB00353636E6F44F6D4A4E4FAC097BE141A6FAB0A773872B747F32C51D9DE257021A36F358BA6377877322820BB497C8077535360AFF6C6460B71D913C77110987D04B1B36815A231AA62866205A0C4DFCEBA5C44797BE40A8427C842FB091BAABA8F62930FCCB73506810929939904105A62A46E7B2C0A09C73C0CA8D18F6C7DB7B20A67C6C0263B54FF07A0620C998F5CF8519ABA855085705C05109CBF653A919E47140168729926AF51C37FA195060B9525C900A80B55E850598E2B5120539105E60424DB93DD0B281BF59CD627984564A48AA61CC9EFBB98AC9342C042BAE6AA49494816CC1B2E2A5A4D250A92EDB9593754CF9792C8187997C6C5DBD957BC44BAD6D21A3A3D97C16A47B677B50116313081481DFD209D7A2B63DD011F0058E4F3824F08C003E76486301C97A63522CB783C49B62FF54C746CB9DC8DCB7F7E83D6E4B88E1450A2332379A0999F5E0B93DCBA630C4A724468F61A44A627C4A99BB5B95F1603171C0703980C2607F246A2C2DB7BAD66CA27C016E1806CCC79B826054BA0F363DD0A77EAB499EF6924CE384A072CB55BE166EBD60BF680B59773597A0B8B255230911C50F160798BC0980CB7393876038F69C3358B44AD3356FF380A70193B7D10C990683CF62FC2E7EB176C2E4C365B1559CE72B03214B34DB183DBC9431AB3D41FA624A01C10E95C687D00CA994658A70CBFF83A60F057202CC61D5C659AAFC7C86021985E380E4E861517583BD71AE7A843A15586E51073FEEE8CB627B0F15130FE182B728020348F5692B84339FA1CCB7D1C85D3868943A0611B122A39AA3FB499784C8C1E3B7A64D2434B0B498320721AD0A0589CC13C89A178CD99105EA819BE904E1AC54DDB47F774CA02A514C513851A9A64E19560F9800C7C835C065D3C6FC59717F262089AACE51842F5E130041FC094D11310A79B872D63F0B58A3D0443008840E5807ABDEA0A5878C5EB0D87EA0330F27DB2470C9C511D56AB43C89E4EA14B46C229E9B2A22906C9FAC533782A632997F198854F2AABE65FCCD877165024358AD4C35B7F778B697B26D89B7F935184103C13B49AA74E7C388390340D77775F84C397645F6E863B28016052586CAF2740C491F4FE16368DB9D89120C7D1481AE647367200400FA4DACF99571E6085F59338D33753763577374C945DC9268998CD9F5BBADA64D67B201AB688DBCB34FC0C1AE05A8370BE00B4B07622A2A97EF661F8A937B5E014264B088374C91D54B72442A4DD50BA0849CA234178B8291A5E4926CAD4A9D9F966744D402CEC274CA84675A77049F822165309212926DE0E6C2D4808C502C94E0AA4851A022C72AA2E467B1298C8121A0C2D6E5BF21837B7FC45357E35580270E6FE9BF2B60553FDA4E838591F1F12DD2C64A6513B78469AEEAB29FAC8504B321855E29715DCA95BAA383B8A1B6A4936DD0524E0B0A9E622881FCB9C7AB882D339CC9DDF1CFF29225A7021FFBB43617771D26109C5B487C2F3558A9A589A8361EC5B4638F5C56BBAA0469F8572BA4BB75F77A4FBCB212D65B5AA28A5B063C8768977678B28D988D8415BF8DD63033183E2D969572779540318909F66C236341C3A1017EE1319CC30815B00543641679A6A2FD3C537B1C3C16DACED7EBACD8C37E36DC420AFC3931346FB3CA0D65787754BCBF2EB4BFD98A8496E9972E747369FB59DAE9B00CEBCDE324684A6989DCE7B5C80099A164832C9778F5C773A9E45D3087733B7A5DE045A9D1463DC8E92A39577018A6BE587C3CEA792C18BB41A6C0A2EB3AB15639C5890C6B7B84B109F04E6EE86A22874AD4457BF85AF2EEA0003CD55F3A10A5B50EC333A6F81576E4E1BD9DEC94D3D2A9E1282695171AC1199A0987DB1E120B5C26CCA663D6EC78D83739F99F33B11714984027E634149D28457E74D8FB433BFEBE4C16D56DB37AA2CD0AA5BDC813A29BBDB030", + "90B7081362EDEC1698E74A36B8C07D7ED6FFE24FAC57A934EFEEC0080B617FB1FAA5A5C7CB33BB6F7D4539864EBEF1F43ED61C2FFF6512D587E0F2D185387B6A924260F45F28D3374FF4AD5090FD3E167153FA0631C84F2EF94138ED56EB606924EE50A5329C7533D56297C0AC3E67C4D03780B378B4C52AC377624D6BFB7A6BC8C4DED581CC6499B4879B2D2AA977AC9113A2AF99A4160A07BA9FC5A93EB8CD8FB242C7B00B462C696699275F70A9290D39914A1C28612161B6AC4AFED3428177789B52096E856CF28C96AF1E8DE8D6A014F14F2B6582BBB4BE5FF80F2B9E141E9D66ED203BCA9DE0CCEDC8AF0B45D602888A4A8B8568DA93C7BC532E2BBCC47E69CEE55E8E127ECEB7463A715190DDAE48853CD25F1FAA72EDAD7D8035F6DCDCC69003A421E009C194A92F7DED987728B425E2C883641E0695DD6E32BD95ED774C586B94F2A4E8E9E66CA9CEB8E71A8E126219A397E80C1039CF52A5F914D1D9DE1AE2C486ED7FE94DB84BF27ABAFB39980321D80DF7E9C7AA6FB4F4FBFFF14902A267A25FCD6EE96B6F377EB07D593C436C725FE2E587BF786B4C29247889910A3FEF19D8A2448C54D1C2720ADE7317A5406094AA9144A25B847FD1569CE8A40D31DEF65229CF0CCA5C3CC4F58BE14A97F35FD35C07687D76CECBF76D11DDE5896C9AA447F3229361863FC9E8CD2258765A00567CC696073EB66F0583341E1337F4DE2FBD46904D0812522965352191E7854A2CB2E7B8D0C2F37792A11AA86DE8F8428FD8D6AFD8285F117F653C80170C202E1D4E1FC71093FB4E21F84090FF40E9A1F7D2A314212F95F8C68E024B37B34FA1317ED134CAC60B756673BFD39E3E19CE9858B7663BD10E98D72F1868A40FB4D7965AE84E6B5AF3E7A856B2494E4FBC2547ECF915C3023467A4192EB9D86331A26610184B9E32B5F4FA0AAD84FF97E748889BCDD97C82AEFE87A2803808457E42D36F7B1DDD9CE83C7A6D758CC4A5F726D4A060B0CDD67F5B2DBD427E7509F1FF6AE1C08220EFEFE3C9803AC905BD9937D5E3C16DDBFA7E5F966FABA8932A8B3A39BB439F8D61A0DBD9BDEF86E7E00159DE66FD6BD279CAADD0904DEA27848454D924CFF42C73C05A09BDDC6697F561F2B7504E686A4BAE4421CB7535301B9E3D456FCA5E1DEF138B2D43C1F62B94EE0949F00B00A63C2FF9888CC3FC5D97571B42F39C5514647F7A64FD903424999FE861238A27F8162D98E24F158248E2366F7B79EA4CF22194AA33B6687C2760E24F506885D12C6977D644F65870BC972C06E7EF025F92934F8C436AC8C9816CDBF94F884F7CA4C77AB19AC75C97D1A39E4D8CD417577F3AD8844509E4099AC275172004ADABB12E11AF71C30DF76685FD269018091B3867C2EC2A2F1D2B094EDFE505D5DE0F7900D5C66E3E7280D608820522E19BCA736E6F719545B201270BD05D5E46B5886F8F7E488F65298E5120699585CD197955E8C2E7186E544E3C7D87A4F40192A91E49565D3C790FAC7E11D3A9723E5409C71154F6C41E62550C1DA3F025E78952569FEB4FBB9AD037E8BC7F7684379033EEB33BD8DF5C176675D0450C0D4D766E8FFB8D7061E2B28F2B63BBA5103CAD764754447497A7F96836187A74766290B5F10D3651BF2E7D0116C58324A5B8DA2E133D3C364AFD3BA9F7045935B200EF44C01BBC43C4DDF0D701517B9AA945F83068BEF1C8871D2C6FDEB3A8EFEE456BE79F2F7D87CDE8A274D43AC05F7EB44604DDF92C7263E32CFEF4FF8B249E0672B0B8A329C3ADAC1F21F77C389B011DA787E8ACFD321F9E2D3F8B81B38BBC2D69BD7921084CC9D3C51D4D44BC0B144A5766132BD612A54DF11555080FA1AF8AEB009F2A55EAB6565DCBDA7B046A02EC586CADDD4F3879CA2F7B50C8431E4E5F86A9C350ADED9D44C2BF663802E67EE48869780EC91B77CAEDBA71AC209523605FB4B3F830C2A12B5C80987025FD39805489378DF80E5422735C3F941D406CAE4DB8265E610F29AD221E7EB32CDF476F5DBA489ADF8B064B1A8CFC1707696C4ACD464C730520CA605F936EE47A671E1CD9D023853EC5AB9E354CC189D3B06F2EA227B5BC2BE6E87041519438C1555F57F8891B834B144006DCBF8FD244894CE5CC98E7BBDB9A8F3F6ABD19467AEBF16D1177DC5C2ADA47CD713A5117F00901F3B463F0DAF549575DCE610977538CCB616C9C10176DF3B89BF948", + "AA6E16BEC77355AB3223DB7CCEE88983FEF389837B073567A72697BE11BA8C5A" ); yield return new ( MLKemAlgorithm.MLKem1024, - "C1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7", - "13E490ADD15409C73E2BC9B0496A9513FC89D3857C5E0A9661E8B8CDA9B3B0B81778863940AA9A970123BE3ACF07E97BCC397BF9E6C245029ED518BA64A20AA1E8154C3C736A1C17B43770AE695C38E96B6EE270DE3C81228497E74206272124E3112FCF7ABE938B9B8B51B874FC4362066559C6AA41E462F912026726377BF6681431BCC5D6AE9567230A5681E3192AA6586031DA7A41891C0FE61F9041C475D33570F2AEBFE03910C43B28E549E5C1C21BE2146352CAE4A66FF8D9ABD769963D93BB6F7C8E1856B2DB4311468645C3D8A824720D2FB93CA547A0A7BB15DB3B6A6E04367837AA378734A88064E033C9B8295099F336B1A80493FB8129F79640D263E943B6E535AAD7459F657A59A1CB12B19C8121F15310357D9125825D745F3C6B788DCA96F743C0F7DA9C033A6F2C8A9F998277F1B053756166DB866D2C2AC427E85AF361C7DED10D292A5F876C8B228A655871BA227C1A56B98B8B962F233C3A570A98A01600296249E64ABD84C70CFE91050CBA61D3588406E7A7A1CB199D07862D65C9F617433D173E557B385FD86EB3A642C75494E2273FC7B904E66B4E58B97CD82549A4635070224E5E039D76E7CC055872A356529E39A27E160D64570B5C92A9B9513A6670A227F7C9CEB3450F55B2AC50C1155AA1611A5DED59A069F43B9E3A9E4DC70F4D1164C830AD7BAB499491115D9201518B60CE8175F43327F8756E3DE2B34F653FC4933381F64EF9926D30686FF981C860A517040BB9EE140D0B541FFCE389F1F51DBB4CB51AC393DFEA5B6A55500D3C305EF88112985E623205516807AB1664CC8ABCC107583B8BB3E2E585F95B89AEDB45E5278C4D7B0960355307453E4A954B51B0A6E817CC16AB1D47839095798E6F7C53EB9BBDFDD0B5005C244774BF3AFA35810226E5D4C7C194C285CB8BD6DC2800963D2C1C7204B43B7290ABE6C17AED934D50F538AEDA48F28527DEF27C331B9F122C2941B884C2BC3E950C1A15A6AD5CD17623339C09872FB899245FB18EF879C5B53602C9436A15B79324753A9090851C3184F699CF75E0648AE1849E401385706521219DAFC8326CE8968BBCA21FC059E62963A532A096DA91457427C2A65B45C22E06038429B52B5F732C87C053E2AB38E67457F3EB967F402B7E0762AE4507AFE1196F22AE9E6797BE959D69DBA5B6FA6493E84EE8B3807FBABAD2C07180D8877F17CA92E08E0356CDCCFA9B9ED6268D19196E0BBD14693BFE72510F6151A9407338128449D3806C230B617525E9E01290AA21EB8BC8C70AC60028492A79B354407F5B8C786239368800C1B2D412DC6B14FA9226D1E765BE1780C0C346BCE1147D692A0BF195A1A2CACB75C1076B59222B214F682B8DEB7B7F51BF7BD9C775AA5474C4CE52963C546170B5539DC39C6ECB963D9C260D7253CF99F404DD49BFB7B4C3A90726B3692704910CFFA2AB8AE528D2A944E80735FE25917F960FC9D1014AAC200380A3591638ECBB44F5975708F584C0C392F2A20D2D1B698706853E28117C9139F303AF622286BE0176AB91812C962BA1C311AA9AA8F334C387424177EA6564EB318F832A68C11DA2418FB4BB6B74F1736955CAFE3170CB467F19F5CBEA7A8CC93692A3673CCD8450AA85860AA04BD4EB8008E63EDAE0A32C4413B3242AA9EB1E94371D8A02BA93173BBC93840EC2347560AED85A97D3DBBF0D7CA052635C794B824BD66798E01E70929FB1CBB81E865E0819749B92063EA99DED733751024A143339ACBA3BC9B065A19006E28B522D2A10B22B325E723E6804A2F19270C5744B1754A13B2128F1C3BE87D3968C8213E5B55442E6749FB21C49396B0B427C030A3D9F397525D8B8953B945C132E5B506B5130708A55C41D8B9F7C9B0781D5340D029E538378640A1A57340DE7697A8CD37B58C64FBD7518F55AA276650C94B40C71B435FC83927740222BA32BD8947B7FE3277D9301B1524ECB735EA358AB6BC41682728DA25B70D1AA2E35A4606BA27351A54C88353A3D455651C3118AA578C4B19C557A6DC1B290AB2C97CCF96665C10FBB67A935477168E0185ACC1155A0132011C4F2523732373BD5425AFA7C061BC66C7883803039296C989224A0BDE9BC4B8B6698EABC6C40A10A842C697B3873D84BBCE048B69DC705E6A7BB6C813BC1491219D429AEC6B9559BC714E17C27600E225AB2398223B9247952B73562B78E6F690561E62951B758AD815E3AC031933CBA45749EF836012456C3E4677347DB502A564A41295FF44449E4E5A53A60A0564A8FA062BCB071C42858A9FEB134BEC8281A57525A6A1D4008483BFBAAFEA86C3BD96BEBE0B842652553542406EC555F8C91AB1953B036A0EE5401C7B9727B7150B2FA50C328B7D5BA337457BB3A7936C0F2443EF816E9B881A7D15C7E6B5FDED996F7ABBBEB1435F70AAEB48B309422C95CD48B66E033BB8212DB82C39F0736E55C7722567CBDF89F1E682343F63ABE16ABF8742CBDBCAB3AF5845269776CEC36920B5B442C986AF62CD5124F10E61B9DB446079AC0A93625A3C15A9709CF01130CB4D721E32B03675B3073B5B3B6E387462399DB7B1F0D18311DEB57C2A33834F8B6BE3574F358A75E6905C0F68A391822E48762E126B62A61194A5707A01083060BA8CDD5376302794565BF647C2F506958C9B4AA0A539EFB859F15142DB0144558D5237067C67340A6BE56544B174DE7998E25E281D2621951ECB4DF063CAAE648DA5B87A69B3D06E779C38C9F8B443BA627398A5301156BA76C27414DD30B29393B77481153DA6AEA138C39AA9049219E4D6C73C2C28EE8F57BBCA2B43B3247E49736261CCA9C52987B0BB7242013BE083B5F770C97E78602A7B0FECB8DF584B86B5C1866FC9C1841C3D3DC17D45BC0B76A6792CB83B3983B553876CCB63DDC1720F782AE08E1A7BA329464E0B8345127867B34EAAC7911AA8DE5BC91FF7479F46105C9E0A5318A780C3156C7C40B2FB7ACD47969E0F7094966BAA7C5C211666B4784B5B10AB1C24677F863615763678BE15A7FBAA38D238253B92C96A76071B50B0CD0222FB4BD57D052CA695E8B3AAF2ED35C131C7EDECC04DB9C25A8EA266B34A4C2B446EC23AB0385501DD4516AB286965BB4322C854AF7CABCF2144B36881899AECC3CCA1D1868AEC77F63AB0EAA85AF792972231BC381EA561F4BA5F455128E90842E44C932F43EE27A0C495A6C784707FA4950C9715D2201AE5A04A0D8820576E322FED4AA20443844E727DD600D58E27691A879124570C858C050E076D003CFA28A149C517E67B58C9F53762149265B9AB37FA3BB32A14911A02FE91A4F8F70329C49A010ACCC0C1259A94A458AC0A99F219C6BBB0141393E09607B94B6138862AE0E809CB5910A48D7C92035496EB2731D70C90F866CE0988896E5944CF5CA000911B817621008244848907E9C75A0241519B08C13282A76B07441953BBCE7C9A55CB2E0442D20415C5455B9B5B6B98F34AC68C33ED0849D826C051A1B1221D08520E8A8285C983FF9025773B6265BBDAB802A03C68F21224A68A7A7FAD62D22AAC1E8E7A6AF04A4C05732EE522CC55587A0A55F1A145DD34724B062BE5EDC7E716360CE0341CB9B7751917207E228C5E452C1CB66043116CA375BEB5C9981219BA8551762B55BF562215F840202E6535903286E31AAE3085CC0A3BF92CC8C3C943DBA7876A5A8CB909CA91746BCCE402712705E8CB84890C983A62534E064A53D013188FB38D4EA69B07B75F04B315CA86E7E9A9E94089DCB9A0A7026CBA238010B48ABAEA51483D255ED7A5700C8C4CFA5BEE4189302C12DE462613BB74B776271D174CC7F3642F7F158F5E70EFDC62E48E36D215264F7227F57006C2FE2B6C4D02008CC85F5D21FB146714424457EFC1F826942B0824FFB30812D5570EBA48FCD365566E09D12E75D4593803F2BA841082FE65501FB2271A902286E3B20F7637F1DA87A779918EC022C85B1242ED78E3A79A3223B5D73C4582E430D46696EB16A3A22BAAD70F88CEC827A65CB3228B44638E0BDC7D361AD40405FB22A3599673B407D8B7B5BB24281042B834F140D3D5C8D3AB2029582C46388A33D370692E2677DA34ACD4A748C69130B8886AFA88BEDE95DD27122A4F4827172029B00708E701F0763B2B5F388FDC82FFAF57AF804725915C432A2B0D671673D41C3BB04C868B35C700045B9A056B7B2359772670C9AC5840C5BB0DC2B9FAC5B4ED12A20251A91085C87A8B24DBCC165D94307965EDE4B8FCE38158BE4BDF3473D160184F745053BD99410091C15BC1288F1130EA2277054CA106438EDBB4F3CF893B5A9007B8C192863BA52A17E39EFDC7060E0C8316936A289684F107DA9B710FC15EE55A9D7439071F7D26129D71267870D23C3FCBA53A325F5F4EFDD0818753D68930C0C2797E74DD2FA9550567AC47E70FE9D84F482BDAB1A8CC149AA7889E4ABF8ED76F68D624DE6", - "C5A8C763C511EE6848FE90241B7358BFF186BBC4B6C0B696EAE1A9CE9B388C1965DF06F76FFC7979EEA1812FCCB17E307E971115CA491DA1793D63CF514062092D284B9C180669CBF357B87CCF45D6FCAF1AA539822BD1992151057C70C81B4D00C6085A419BD7B93D4F6D708CE9745F1C7007F37B57C654C0BE8B951847271494FC23DE9DEC4454A3C0A6107D53A570115430EE2330508DA9B67A915C6391BA12FF56680B8C8B5CF133DBA70198B788B5AF664FF776910AFCA238A4861267ED9B0E42CB4920B8011B1A3797C214B0715F7EB164D6D1D3C67BAB22E6C07BB617608740D98A1F381FFF9C43DC17CD1A568C2B6FF9FC0A081ED729CDD6D8B5A9FC482321400A2C0F0FFE1F9E5469BA4822AD6C967E854CE4155541D84ED6D1AFA6CED139E876AFD711CF0B732C4969BB4D5E940BE686D8E0336AF3B6C1566E49FEB3BAFDCA994E262DF17FA85596E8544D56FEA430B93C99770FF155DA4DF18F45F2EEDFD07349CD467FE522EE9E7AFFA2059DEB3D812C981B4D45FE0519FC5115940AD9E0BC36FAB95EBCEADA29442D8A2912D765A5D72EA88B7D043AB94F0240387FCD3A462148042F5DF105AD3ED9951253EBEC64CACBC7089B450E74EC8E0C84A5748CDD13664F91E830DEBA7D6A7C79A394420E26DDE66585D8A90456964C8D1933C959071D6688F979CB7D60F8FDBCC17D9177B395E12BCFA372ECA0B74CDB264299AFB6AD57F720A10E1B08695C9838791972AAE361B61BD191AF410505ACA62E9EB055D73443CB2003B77A486EDB58451CAC8204AA68DCC489B40F0098FE426B156C4C4B8C23610D682DBAD6D2F74566409C9DAEC9739DF320DE679CB432A55434AD4B8AFF5FC0A544CA275742EED6917CB6B3F9916A8458C7F5063246EBF47FF20EC8FE04B7E5CD37E9A11C654F964D5E3BB34404572B7C2EA39BC482696BCDDC76EFBE3820E4CC662D3340A4FE3DC85F44EC4599F813B0C14F3B9540F906E1DC40BF9634743937EA4F34D79115077F0AE09CF317C0E004A21901911F26632A826F65476732BBFBF15B657029DDDFC1F333863332C67C415FBED95F078DD3B66D650B6BC78EEDDAFC3BA2C47337C0AF44BF1AE8539377C1655330D68B97527CF9DF13A2A418F6E5E1C61089E09717D6CA06A9B4546E0E9CA4C78A533AB648A38914FE9E8407A5404D687B86694E3EBB5342A54100DC5FC81ADA0FB01A3A9440EFD4C9C694BC5F29A9AD513C0469BF85ECAD67E4C2F725DC6FBE0A926EECD77E5A4F6D08F30A9621D24215731B81C1039AC1E7D92917EA2BF686DF95C7FC2BE16DEDBCD6142291C025BEADED6A7B8D17D20E2712DFB4985B351C9EDE71495C7A759776627AF670C4107431441489352B0852258AF90E53F8BDA2A95A84113358C3896D11043928CDFA6E293315A2BF58B5310D47C7901D7498E5125F498F265D4F3F525E1C2A1CE5CDB76F27A803E8CE907DC87F95A676D1A6D009A9FE1658A6AD162E14EB571547940020F45949ADCC4372D0E10122BB4DDDC7BD461B93AE92B7A735B7297D8432FB2B52030D470CE3C7F703AE04F4059DB091E5A51DEB02C87DE63E796B74A640F7B61E06BFEE6EC20DE6C84E0A042FA2138B769F052FAF408725AB40728A183141FE3D72DAE6FE456FC6855CEB6F274A221F01E2F7221A6980465079FAF749415653DF8C681AA2760E116EB08D988E22CCBE85498023B9E49DC59D08BD8805BB34EA1625904F220DE43754C081CE1BCFAE84CCB370B9C6E39B3C325C7E4A3270A78E91ED7ED89EEF8FEAAA471869E5DCCA09E027B07028149CA55E873855CD5C0CFCB6F3F71A9070FAEAD3ACC0B8B59DFB553C275FE138061CC42976B2C68F461090B7BDF1FA7EEF62C2ED16C42FC20A53A984492E579125F0CAB1A22A11E8ACDE90B657A4BFDD66931985EEACE6616259D8A70FC2EE622DF95F081C134ACAD18DD420C12870F577AC9AE4C882994FE19E4AEA6282524F8F7784F47AF9463B5BCEB37E6CFED95999D38A0408C91D6E609698BDFD0ED7E3B0369ADAB16A1CC2E44F9F803F5C8F7CD87B1190DBE05DEC987C3760C472A5C43011C98B6D6EF6909927A81DB3AE40EBFF9DB6D7C49C34C623482277FF608AC8DCB63B5402BCBF279E1F996D743E756F8FF74513B6107007A4F2AAB970E87FEE06A9C1AC2C6763AD407FC8429A52F6FBBC1F3AF31D1AFA4F7B6B47D40BDE", - "0FD1E5C9576B598CD1A90B7749A31487E996470FF9C234127A6DDB7D2DA22B27" + "6D425036E686687B92FA3B5D80A5A066452B762783B3D09744B819CB8BC7A97B26AA912B533A0492451940DCAEA9A410020C55FF0984B0819BBD54C1BAD61C0E456F81F81CC4F5B181666DF091CB478909C1946DBB998FC151B8666C9181D05247143E884464B70776FDB740516412A48321DB3588418B0F43B44C889C6950CA0C746BB9D22C22884664B65A7AD8D5403E6C5871155458A8619506163F125581351EAFFC5AF3107A153A1397B07E9E817CFABA9C5F654AC27C8244E30AF94A1351F2414DF40AD8E9A24CC46E16869F61B9014E4A6B030605151624BE8ABD40540D81E232AA48A861D680D6B3950511049CB80697F0131B15C25DA2408A64044DEC856F01C6B827695EEB4D0EBA9F9F309EDB20551E9B48F1B7899ED2764C265B63668AD8E877252B53CDDA125FA603AB3C5BE9286DCB88668DA5817761B65778A68280C817A4A22B782DDEF15D6B674E19B9882CC415BB9A18175906A77428780205C01C9876D338696B310F1A7B62DA0129C4BA58289357493865F935B2F005BFEAB570C46B59C0195FD82968B7B233E086E38B28BB6B5F67E4B20B224527309F68549A9E5167842C62AA805C3A5A0194277631D36197E32F3F480F5C7B4863B5889E795C1BA6252136C2EB7289EA2781363C220364CF66D2CC7D16AE58D14F21C3BD9199669BE6B903F677ADCB3DFFE22F40911011C6BD8AFA0EF1359A6B027640C327B4C859592071480A134FC06B2D024F209561EFBC2F0A0B65D649AE0DE82F3352C4698B2F4393882403827DFB9B9F25355FDC3E2A9863E68C8B3923A821113C86348FA20B356B69C35AE0A6AF432C14F70465AC8902F44CC5D50D0F3C95982758055924A8285B23345C400B7F517B27E1A79C1F8959D027A18C75B6AB8107201BCEB8EC7D11CA26A823074BA12A05399B132BAD09B16978C5BD2DDA2CD82B0AFDDAB5A2EB6A05F31EDD35820EC839B6524256778E10D666659932125681EDB1A534094890772977A993D409626D47A78E78873401B232CC30FCA10E4B4CC1A5015DF969B04B049BD1BB181B15A8FEE5A339D41F462322077B55CC17C70259954DA4CECE3942E0D2801C4A55E64607949165DAF575A15087A358AF023440C58930EEA06C59C74473B8A85840849AE51E68449BC1788C8343193989B96BE0924CE44239D180384286FB0841D99653C16A2AA2414A6E3815B0FC4A1DF34035B2A3D85AA4A725B945904125FC5EB2EC53F6393E10C9B78C35C658A27EF8E092D20C3F5435AE21C930D3B7512E9470CCE0C11FE0091922195906BAE7069F47F6726C48ACADA6B01DEA4C29F14422D367E0E216DCA511F4F2000B1A8E04103DA9D27224C6BF77682C347A47DAF525E5C6A8728A4FBC1078E2651BA3AA250AB63AEFF6CD2D3406EBC74BBA70894A651192B7A509A26B028786FF3623082626F00CAA3B55176A24299242CD8981A102757BB29B8179B7832E8716F3CA96928C43BEC91F8546A22AD325D665499C8A5EF126A6E238847EE328AF0177EC06C3CEC931EAD96E8883702421459F633842E39E9E51A8840289D2D5C4E4DC09966441FED735C0D174DD3B68B94A9CF23A6D4DB83D625AA04034B3409870F77B8BCB362CFF7891622B2FC3D90CA9CB8084B610B1A907F4D4B0BFE24D9D24C0A053C9194A3FCFF3ADCF956540022179576B44183062937C430886934BCB34734B79E13DCCA6B1967502A132BAEF88B9A972216F488E2508464C2C6A4BE333A3397D4C9792D9091788553464229151E52A2C2604C171C5FCE0AFA139C9CEF1B453835DF6472A4B400126EAC38E96B42452187FE1C62D8B177EB97ED2281FA8632B95A71199E896679B7512A9BF3D7714176BA9C87988653BA392004516829DF8351D15157C90716AA9ABC17BA86AFB4AAA77B154B9A1B9F18BA0E75C5C9EE97097A05E7AAA243E058D19174315CAB9737532DDC50E99730F53E239094786CF726380C8894236131609CC50B441AC0B6C60512FBDE19732796F9047BFAB401E56C097D23C3CE528CE851077ED6824514AAB11302087AA22C9D13DF0F2C57FFB916B46B1FF82304756CC376647B37A25C181863CB38F04415A661B33242482A579A19B1B1E4CE98D64040283172180D609DF323D64C99BE2220B6AC16D4CEC15B72C485A529CB821197101D439BA2DB6154E6E30579E754169857091D9D7FE45F6047794947B", + "A8E9AC28865FB8B9B659A12B1FDB2A83141FF1E09DF513B835350B76D5A43AAC54500A56E42215E8A88F14F69EC1287671868D88F1BB8C9381D23C157798C62EAB48AE92694F5577984A774E6962C0717C6604B2CBD4502C627E3807AC56B6A8C876B8847368276BC19CEA8CC7E13FB479A3379959C0FC3126CA565175B2D7909C46966235866A8BE4BBF8636661CC10A7D28780A571DB9B7C82576C7901AB93F4889147CB144B546EE539A213071168BAC92C6987D26DF09A518B442449989D02B54346E2614B9256B73248CEC04C63FC6B6DAC61D3B87A25D80398E2233D383113F2AB31053973277105D02E139029FB56AF9963BBA5AB4CA29A0669F0A6D3D3283F658AB015C86FC8AECFFC91954C6A75C266D7B38D243655D4801DF4385C818764850212EEA22A3B1725CC231128428A7C48854CD815C2752D4D883E3F150FE8F9164306C3E1F6273F460EF7C9856FB53EF248BEA8912C20E1575F26A6AC19444980A6CBD988125A7CF715037DB36B0B34349E93AAD519150D983DF402CA49A41AFDE60AD23C7E19E57235D71BE73C6E61D0328560121847CE0BF66F53C76BB39ABD8ACC6A003B9F163075F056A657FA1B3864066D3CABF2F722818879DF847D2E0401F102612A2192B6856EFBF9BF68033B934502539556EEB14518303078F0399AD777FF204E8D92BBA05ABB2C95C72441183ACCCFBD71952B43970BE492EE9B6ECD811092C800A01476BFF4152760C752231662BA90AC55C705965C8BF7477AA801614BC8ABA59BA2EABC5AB8B5DCEC9335E32C079B9B6AF03735B011F8249C23F6415D9190EA070BC34041B67592B5A0995F482E17357671D122E16134E3AC42CED6CF2DC186D556B59975AF80B958A2EB672214671183132FAC465A0456725999D81B0E27F4494514B7DB76CE1C307229F4C2063584A1B4C40D07551D560228C1174BBA14BA99200402597C319BB23434203935FA9C6CB3702AF6373452BB743033CDF08301EDEB770086735AD0050D870DAB338510A20F823032522C8E66120DEDFB9962C7C661944492C029F4E97DB9B8718E04B1186ACFE18B3685A0C8EB07B5EF30B01E8A1CBE732A948B7902111D74783F5244866611231FABC92D296D4ACC57A2F52CCDA33141868F0474B42A57507165176639C300CA59E4897CBDD824E1C78614537D57941B2F950480045A9593C4A7859DF3516784FB17FA741BC6506F5CCBCAABA4C9A9F49EAFF45B69E919154B62FA41AF0D9B11C9613342A63157C67E2D7052DD997E7419660F810C27732FBDC99E9840BB2DE1678DF795681CBF81B178D94333831A27E1225EDD75B330021CB9720ABD26B554C60226995E5E63C14C5C4E8916866D571C6CE7522253565EEA6CEB95ACE11514FD08A42A349237E835723588D568A8B2B1875FAA1A8B1891CFF081D269723806339342B724E0603A7407F4A55EA85355CB89077BA06653EAAE8FD640518026F91B74D6457FC97769897ABCC750C031A74FE9F48C94B06591554167C92624636F558710CDF64FABA2A165B56605011BC1FC9ACD4976CC4697CF21B0B76168C68227CFFACB291A23EB144B95A7694C434993D8996AF46C35788639B48A084500FA27675AF35966297871A76DFCB6A70DA1C44DB37117542DC42C0EDBD60C17DB62EA3AA06C554C1B3566399B77F9EA816E6C121CB827593B42C6A12AA8491F4AA59E8976ACADE8546CE0C690D6C013975E8F2B7A6E1020CF3659D750A7B271B8C2B17D14B07E420726B93B040B300B661A7FC6B8723F4A127FD8AD0BCABF23B03FAECA7997811E14609D34A17FC0D50ECC9A4A69DA30BA440A9990470E78B8CD077D33B36B3B9AC0FB9517E73A5E2A49C650C35C2D8A9E2B961B2DBA71C8E93558300FF09584D143B0CF213629C8A5D754C712F1BB12A06C813718B26C34B495A0FABB6BD434324DF11588DA9C29A84D1295CA7475AACA63C3ABD9064D4928580A9371D6B317E5B1274A5BBF25C600637CBA9C3F8E8A805B4A5FDB240588367987389F028625B66BBFA74ABC9016BBF9EC347ED9AFCBC4073599BE40B75D43653B5404156F083441E20C8DA408EBB27FA00AB1C476586D566DC20723FAA4657C2170D6CB66A0DB8380E314B0914978D97DF974B738719E715B842CF53CB4AA98F316456D425036E686687B92FA3B5D80A5A066452B762783B3D09744B819CB8BC7A97B26AA912B533A0492451940DCAEA9A410020C55FF0984B0819BBD54C1BAD61C0E456F81F81CC4F5B181666DF091CB478909C1946DBB998FC151B8666C9181D05247143E884464B70776FDB740516412A48321DB3588418B0F43B44C889C6950CA0C746BB9D22C22884664B65A7AD8D5403E6C5871155458A8619506163F125581351EAFFC5AF3107A153A1397B07E9E817CFABA9C5F654AC27C8244E30AF94A1351F2414DF40AD8E9A24CC46E16869F61B9014E4A6B030605151624BE8ABD40540D81E232AA48A861D680D6B3950511049CB80697F0131B15C25DA2408A64044DEC856F01C6B827695EEB4D0EBA9F9F309EDB20551E9B48F1B7899ED2764C265B63668AD8E877252B53CDDA125FA603AB3C5BE9286DCB88668DA5817761B65778A68280C817A4A22B782DDEF15D6B674E19B9882CC415BB9A18175906A77428780205C01C9876D338696B310F1A7B62DA0129C4BA58289357493865F935B2F005BFEAB570C46B59C0195FD82968B7B233E086E38B28BB6B5F67E4B20B224527309F68549A9E5167842C62AA805C3A5A0194277631D36197E32F3F480F5C7B4863B5889E795C1BA6252136C2EB7289EA2781363C220364CF66D2CC7D16AE58D14F21C3BD9199669BE6B903F677ADCB3DFFE22F40911011C6BD8AFA0EF1359A6B027640C327B4C859592071480A134FC06B2D024F209561EFBC2F0A0B65D649AE0DE82F3352C4698B2F4393882403827DFB9B9F25355FDC3E2A9863E68C8B3923A821113C86348FA20B356B69C35AE0A6AF432C14F70465AC8902F44CC5D50D0F3C95982758055924A8285B23345C400B7F517B27E1A79C1F8959D027A18C75B6AB8107201BCEB8EC7D11CA26A823074BA12A05399B132BAD09B16978C5BD2DDA2CD82B0AFDDAB5A2EB6A05F31EDD35820EC839B6524256778E10D666659932125681EDB1A534094890772977A993D409626D47A78E78873401B232CC30FCA10E4B4CC1A5015DF969B04B049BD1BB181B15A8FEE5A339D41F462322077B55CC17C70259954DA4CECE3942E0D2801C4A55E64607949165DAF575A15087A358AF023440C58930EEA06C59C74473B8A85840849AE51E68449BC1788C8343193989B96BE0924CE44239D180384286FB0841D99653C16A2AA2414A6E3815B0FC4A1DF34035B2A3D85AA4A725B945904125FC5EB2EC53F6393E10C9B78C35C658A27EF8E092D20C3F5435AE21C930D3B7512E9470CCE0C11FE0091922195906BAE7069F47F6726C48ACADA6B01DEA4C29F14422D367E0E216DCA511F4F2000B1A8E04103DA9D27224C6BF77682C347A47DAF525E5C6A8728A4FBC1078E2651BA3AA250AB63AEFF6CD2D3406EBC74BBA70894A651192B7A509A26B028786FF3623082626F00CAA3B55176A24299242CD8981A102757BB29B8179B7832E8716F3CA96928C43BEC91F8546A22AD325D665499C8A5EF126A6E238847EE328AF0177EC06C3CEC931EAD96E8883702421459F633842E39E9E51A8840289D2D5C4E4DC09966441FED735C0D174DD3B68B94A9CF23A6D4DB83D625AA04034B3409870F77B8BCB362CFF7891622B2FC3D90CA9CB8084B610B1A907F4D4B0BFE24D9D24C0A053C9194A3FCFF3ADCF956540022179576B44183062937C430886934BCB34734B79E13DCCA6B1967502A132BAEF88B9A972216F488E2508464C2C6A4BE333A3397D4C9792D9091788553464229151E52A2C2604C171C5FCE0AFA139C9CEF1B453835DF6472A4B400126EAC38E96B42452187FE1C62D8B177EB97ED2281FA8632B95A71199E896679B7512A9BF3D7714176BA9C87988653BA392004516829DF8351D15157C90716AA9ABC17BA86AFB4AAA77B154B9A1B9F18BA0E75C5C9EE97097A05E7AAA243E058D19174315CAB9737532DDC50E99730F53E239094786CF726380C8894236131609CC50B441AC0B6C60512FBDE19732796F9047BFAB401E56C097D23C3CE528CE851077ED6824514AAB11302087AA22C9D13DF0F2C57FFB916B46B1FF82304756CC376647B37A25C181863CB38F04415A661B33242482A579A19B1B1E4CE98D64040283172180D609DF323D64C99BE2220B6AC16D4CEC15B72C485A529CB821197101D439BA2DB6154E6E30579E754169857091D9D7FE45F6047794947B474ACB46790D527994365E95B582F5A89A0CC64CA298A6964F498921363C94A816B646E0CAA1B5BBB32A770713E5252E5E9398734EAE0CC99BF38927036FC44A", + "CC3BCA4285451200842ACFFA022C8EC7514C489D68D995187A062E12A4432C3C51E5373A5E63BBC2BA6F197E086CACE11FAE53DC7836E8E9AC389B1F4DE175D82E5C6BDD2EB3650443EB873D23BB71209CAD3A42A1EAD2C571181C1FB18F3269C671A6CBC29EB058FFD64E1C2CCE1D6946B3ADCC66DF896B11D7DF980B76B5E12CC6AA2CBD1F5489FC7F116726659C8AA3724F6D673C68B18936D0F7801E416863192DF45CA25C9A380CD9A061F58E8AEE18041732CF05A2C7BCEE0349B2020FC3FD8F55FBD0BD5321D77E7206D70AE03604F6EE3102F5EB3C5B04F63A352CBD8FBE95C915C3E47166787ACF2E7B751E626C8CFB40EABFC462A6C90409FB5CFBB36267CCEADF34809CCA3D716A15CC8C359307EE4CBFF0541ADAA9E3A36B5530D1A7CF880F78F1B46A5537994949004867385EC2536C4B77BA016416BD851F67AF6B6F822F97A8D627C45F69609C9DAF066154F1F1A759923EE26D68F141128CC125A5A91F0DC0AA084C4873A34D382CA026B2DBFC414DB7FDBE54663F8D69F9DDD84271EA27E1344B5080287E9FEF2960407100C94678260CA2D6962C7FE448EBA813FFCA34BB441C895C9514BC3EAB1B08979789FEAE3FEDCCC214073DB018FB2575B0974B3D5ACA44AD519213390EBA67E3E9C3A0325C136FA0693314938CC4373F4B5C91609437EB9F621315122C8796CF8DFA74291CDBDC2D09821C0C9F107164FF3ED66C9D5BF3FCF70FB9360C3BC1FD42E689E034E585C640139B2729032FD048C98C8B2C8D63037BB12941D61395D42BD1CB51BE5FBF1B5B07E04C21E4A9A45FC41966943F8DCBEFF1B100DE3FCD0ED8BB97CD9FA8BCA29FF487A2F4AEDAAA51CD082F60F9D66D9D12DC1E7775CEA470BD2CE7ABE2CD99C43FF16A0EE680189EFBF288F131C657587566EA75D24E921B56DCD67307F281299EBF415B871A6880E7AF7ABC108E5CB431C0E605A5D2DD7DF87E82FA1B7C4957B7EB28C2A833F37B508D2B888FD71F381B6E3225AA95201C34EA2FFB38C6B1D055062F0CFD34F285DFF7C6DF08F7705E1980B45D0DAD3464CD337916E2ADD3890D53D7C9A23C1FB3B794302925A6A9C5BAE749EDC9704E7E68CC2E952F2AD1817DC55E4199923282E691077DFD6AC9CD1DFCEBEE3810923ECD9ED1A0D4339475569147476C2C1B28FC37419B621C6FFF17F169720F80882CFE80D112BA3C16AD634494D4D598D245C328BCED946FA0F8368AF188BE37B286535ACA9739105C19D71BC60FFE03D6F4C8FE71E1BB6BFC1596827E0179E41CC6E070A02711D2D867B66F0B95099F4B0C17CADED30E008AC718DA9E8D9B8977708BEC407C05C0CAA0518511F57C9DCB952D5222952BCF777BEA53F0B290988258AC692018620FF57D894380A68F4A88DFFE8424846920332F597E3D2B35460B3DFC19569B771C4ACC12D2A45E294618C1A59C6F05355B85F0AB955AAF7F504572B0D4DDA1CB60B5D6C5A092B1BD2DABA010280FFF02B816487C7E0739287041DA5C4B11B01DD780A5975474DA56EE69F4B58542E90654A5F7782CA17C6F406D58162C77B139DF5352D1EBB118FB4E356E8AB5BFB5ADB6FFAB48ADBEEF1E8FF1BC2BB8EAB82CD82D59AAF83DDD6695475A59A26AF2105D87B4AC18ADD0E5A498C39E7F6E34E4DC083B095C3B5604FDCBEB824A3F8343CB5C8DF7894E84D67D6CE16A9D1000B2A18833DA14ADF3A15BB73BCFDC44597F1FA4EC5CA715D7C2BCB49D9DE14620D61F964FCFF47491E5E1805E3CF1ACB15E15D7454080E52F2B23A4F41A1018167A1267769D7E8100AE7D646512B9400B56FBAF796CE680A0F2F46B55223566B3A89261D4D94986E22328F20E49488B454E222D55CB012D9A6D8E02B78ADFE41658DEA2F2FF55918C5DBB28B39593DDDC9EB307DC09BA62AAF25D85208AFF056793BE6DF2A0E4BDFEA4AAC979C492F51E26DA3C762E23A834AC38A401BD806C63E457DFAC59DE940069B22240BDE06DC04412CCE8B2B363292AB61EE3958DE4E11CBB4637D0F514A11261803B1F0EEAB36B3B238AEECCF5E0DA02C415BE7D598B9D142EAA087A63B125F80F5A7AE3B94A623666EB246DDFA5D41B238A51741F441DE8386A0B5C3A52455B424F2C72A9EC647F1D2EE9452EFF078AB1FB086ACCB8F41CB34B96A555A504F607BBDCA5B95353600A0584AB0BF4534C375AA377B564422A125912D17CA0", + "5C7B5FB8B30A4F816925C8B7038ACFCCC5C82FBF574F501FD394D0C5E2F3D9D5" ); } } diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs index da5a2d6a7e9..791c64ff9f8 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12CollectionTests.cs @@ -178,7 +178,7 @@ public abstract partial class X509CertificateLoaderPkcs12CollectionTests #if NETFRAMEWORK X509KeyStorageFlags.DefaultKeySet; #else - PlatformDetection.UsesAppleCrypto ? + PlatformDetection.UsesAppleCrypto ? X509KeyStorageFlags.DefaultKeySet : X509KeyStorageFlags.EphemeralKeySet; #endif @@ -301,7 +301,7 @@ private void LoadKnownFormat_Fails(byte[] data, string path, X509ContentType con Assert.Equal(contentType, actualType); } } - + if (path is null) { Assert.ThrowsAny(() => LoadPfxNoFile(data)); @@ -749,14 +749,19 @@ public void LoadWithDuplicateAttributes(bool allowDuplicates) { Pkcs12LoaderLimits limits = Pkcs12LoaderLimits.Defaults; +#if !NET10_0_OR_GREATER if (allowDuplicates) { limits = Pkcs12LoaderLimits.DangerousNoLimits; } +#endif // remove the edit lock limits = new Pkcs12LoaderLimits(limits) { +#if NET10_0_OR_GREATER + AllowDuplicateAttributes = allowDuplicates, +#endif PreserveCertificateAlias = false, PreserveKeyName = false, PreserveStorageProvider = false, diff --git a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs index b2005ab6052..2c58efcda33 100644 --- a/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs +++ b/src/runtime/src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/X509CertificateLoaderPkcs12Tests.cs @@ -179,7 +179,7 @@ public abstract partial class X509CertificateLoaderPkcs12Tests #if NETFRAMEWORK X509KeyStorageFlags.DefaultKeySet; #else - PlatformDetection.UsesAppleCrypto ? + PlatformDetection.UsesAppleCrypto ? X509KeyStorageFlags.DefaultKeySet : X509KeyStorageFlags.EphemeralKeySet; #endif @@ -302,7 +302,7 @@ private void LoadKnownFormat_Fails(byte[] data, string path, X509ContentType con Assert.Equal(contentType, actualType); } } - + if (path is null) { Assert.ThrowsAny(() => LoadPfxNoFile(data)); @@ -744,14 +744,19 @@ public void LoadWithDuplicateAttributes(bool allowDuplicates) { Pkcs12LoaderLimits limits = Pkcs12LoaderLimits.Defaults; +#if !NET10_0_OR_GREATER if (allowDuplicates) { limits = Pkcs12LoaderLimits.DangerousNoLimits; } +#endif // remove the edit lock limits = new Pkcs12LoaderLimits(limits) { +#if NET10_0_OR_GREATER + AllowDuplicateAttributes = allowDuplicates, +#endif PreserveCertificateAlias = false, PreserveKeyName = false, PreserveStorageProvider = false, @@ -788,7 +793,7 @@ public void LoadWithLegacyProvider(bool preserveStorageProvider, bool ephemeralI // EphemeralKeySet is not available by name in the netfx build. const X509KeyStorageFlags EphemeralKeySet = (X509KeyStorageFlags)0x20; - bool expectLegacy = (flags & EphemeralKeySet) == 0 && preserveStorageProvider; + bool expectLegacy = (flags & EphemeralKeySet) == 0 && preserveStorageProvider; using (X509Certificate2 cert = LoadPfxNoFile(TestData.SChannelPfx, TestData.PlaceholderPw, flags, limits)) { diff --git a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj index c6d5337565f..97e90e69a91 100644 --- a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj +++ b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj @@ -57,6 +57,7 @@ Link="Common\Interop\Windows\BCrypt\Interop.Blobs.cs" /> + @@ -75,7 +76,6 @@ - diff --git a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx index acec0d88440..9994b32d5cc 100644 --- a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx +++ b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx @@ -162,6 +162,9 @@ The specified hash is not a valid size for this hash algorithm. + + HashML-DSA '{0}' cannot be used with hash algorithm '{1}'. + The size of the specified tag does not match the expected size of {0}. diff --git a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs index feb43d2caa4..9344f75762f 100644 --- a/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs +++ b/src/runtime/src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/HashAlgorithmNames.cs @@ -6,6 +6,7 @@ namespace System.Security.Cryptography // Strings need to match CNG identifiers. internal static class HashAlgorithmNames { + internal const string MD5 = nameof(MD5); internal const string SHA1 = nameof(SHA1); internal const string SHA256 = nameof(SHA256); internal const string SHA384 = nameof(SHA384); @@ -13,5 +14,7 @@ internal static class HashAlgorithmNames internal const string SHA3_256 = "SHA3-256"; internal const string SHA3_384 = "SHA3-384"; internal const string SHA3_512 = "SHA3-512"; + internal const string SHAKE128 = "SHAKE128"; + internal const string SHAKE256 = "SHAKE256"; } } diff --git a/src/runtime/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs b/src/runtime/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs index 3a83e2ba346..0face5c7c0e 100644 --- a/src/runtime/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs +++ b/src/runtime/src/libraries/System.Diagnostics.DiagnosticSource/tests/MetricsTests.cs @@ -13,6 +13,10 @@ namespace System.Diagnostics.Metrics.Tests { public class MetricsTests { + // We increase the timeout for remote execution to allow for longer-running tests. + // Ensure RemoteExecutor.IsSupported, otherwise the execution can throw PlatformNotSupportedException. + private static readonly RemoteInvokeOptions? s_remoteExecutionOptions = RemoteExecutor.IsSupported ? new RemoteInvokeOptions { TimeOut = 600_000 } : null; + [Fact] public void MeasurementConstructionTest() { @@ -53,7 +57,7 @@ public void MeterConstructionTest() Assert.Equal("v1.0", meter.Version); Assert.Throws(() => new Meter(name: null)); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -82,7 +86,7 @@ public void InstrumentCreationTest() ObservableGauge observableGauge = meter.CreateObservableGauge("ObservableGauge", () => 10, "Fahrenheit", "Fahrenheit ObservableGauge"); ValidateInstrumentInfo(observableGauge, "ObservableGauge", "Fahrenheit", "Fahrenheit ObservableGauge", false, true); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -99,7 +103,7 @@ public void CreateInstrumentParametersTest() Assert.Throws(() => meter.CreateObservableUpDownCounter(null, () => 0, "items", "Items ObservableUpDownCounter")); Assert.Throws(() => meter.CreateObservableGauge(null, () => 0, "seconds", "Seconds ObservableGauge")); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -169,7 +173,7 @@ public void SupportedGenericParameterTypesTest() Assert.Throws(() => meter.CreateHistogram("histogram1", "seconds", "Seconds histogram")); Assert.Throws(() => meter.CreateObservableCounter("observableCounter3", () => 0, "seconds", "Seconds ObservableCounter")); Assert.Throws(() => meter.CreateObservableGauge("observableGauge7", () => 0, "seconds", "Seconds ObservableGauge")); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -228,7 +232,7 @@ public void ListeningToInstrumentsPublishingTest() // MeasurementsCompleted should be called 4 times for every instrument. Assert.Equal(0, instrumentsEncountered); } - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -280,7 +284,7 @@ public void ThrowingExceptionsFromObservableInstrumentCallbacks() Assert.Equal(11, accumulated); } - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalTheory(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -376,7 +380,7 @@ public void InstrumentMeasurementTest(bool useSpan) Histogram histogram6 = meter.CreateHistogram("decimalHistogram"); InstrumentMeasurementAggregationValidation(histogram6, (value, tags) => { Record(histogram6, value, tags, useSpan); } ); - }, useSpan.ToString()).Dispose(); + }, useSpan.ToString(), s_remoteExecutionOptions).Dispose(); void AddToCounter(Counter counter, T delta, KeyValuePair[] tags, bool useSpan) where T : struct { @@ -723,7 +727,7 @@ public void ObservableInstrumentMeasurementTest() ObservableGauge observableGauge20 = meter.CreateObservableGauge("decimalObservableGauge", () => decimalGaugeMeasurementList); ObservableInstrumentMeasurementAggregationValidation(observableGauge20, decimalGaugeMeasurementList); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -875,7 +879,7 @@ public void PassingVariableTagsParametersTest() PublishHistogramMeasurement(instrument as Histogram, value, tags); return (decimal)(value * 2); }); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -963,7 +967,7 @@ public void MeterDisposalsTest() listener.RecordObservableInstruments(); Assert.Equal(13, count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1034,7 +1038,7 @@ public void ListenerDisposalsTest() listener.RecordObservableInstruments(); Assert.Equal(7, count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1102,7 +1106,7 @@ public void ListenerWithoutMeasurementsCompletedDisposalsTest() listener.RecordObservableInstruments(); Assert.Equal(7, count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1147,7 +1151,7 @@ public void MultipleListenersTest() gauge.Record(1); Assert.Equal(15, count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1184,7 +1188,7 @@ public void NullMeasurementEventCallbackTest() Assert.Equal(2, count); Assert.Throws(() => listener.SetMeasurementEventCallback(null)); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1225,7 +1229,7 @@ public void EnableListeningMultipleTimesWithDifferentState() listener.Dispose(); Assert.Equal(4, completedCount); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1268,7 +1272,7 @@ public void ParallelRunningTest() Task.WaitAll(taskList); Assert.Equal(loopLength * 17, totalCount); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1337,7 +1341,7 @@ public void SerializedEventsTest() Task.WaitAll(jobs); listener.Dispose(); Assert.Equal(0, instruments.Count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1441,7 +1445,7 @@ public void TestRecordingMeasurementsWithTagList() expectedTags[8], expectedTags[9], expectedTags[10], expectedTags[11], expectedTags[12] }); } - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1529,7 +1533,7 @@ public void TestMeterCreationWithOptions() Assert.Equal("10.0", meter10.Version); Assert.Equal("Scope10", meter10.Scope); Assert.Equal("TestMeterCreationWithOptions10", meter10.Name); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1662,7 +1666,7 @@ public void TestCachedInstruments() Gauge gauge12 = meter.CreateGauge("name9", null, null, t1); Assert.NotSame(gauge9, gauge12); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1728,7 +1732,7 @@ public void TestInstrumentCreationWithTags() { Assert.True(string.Compare(insArray[i].Key, insArray[i + 1].Key, StringComparison.Ordinal) <= 0); } - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1748,7 +1752,7 @@ public void TestHistogramCreationWithAdvice() Assert.NotNull(histogramWithAdvice.Advice?.HistogramBucketBoundaries); Assert.Equal(explicitBucketBoundaries, histogramWithAdvice.Advice.HistogramBucketBoundaries); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } [ConditionalFact(typeof(RemoteExecutor), nameof(RemoteExecutor.IsSupported))] @@ -1771,7 +1775,7 @@ public void TestRecordingWithEmptyTagList() counter.Add(1, new TagList(Array.Empty>())); Assert.Equal(4, count); - }).Dispose(); + }, s_remoteExecutionOptions).Dispose(); } private void PublishCounterMeasurement(Counter counter, T value, KeyValuePair[] tags) where T : struct diff --git a/src/runtime/src/libraries/System.Net.Security/src/System.Net.Security.csproj b/src/runtime/src/libraries/System.Net.Security/src/System.Net.Security.csproj index 032dc286c46..c82d7803598 100644 --- a/src/runtime/src/libraries/System.Net.Security/src/System.Net.Security.csproj +++ b/src/runtime/src/libraries/System.Net.Security/src/System.Net.Security.csproj @@ -442,6 +442,8 @@ Link="Common\Interop\OSX\System.Security.Cryptography.Native.Apple\Interop.X509Chain.cs" /> + diff --git a/src/runtime/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs b/src/runtime/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs index 3bd0c7142c3..48ece237432 100644 --- a/src/runtime/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs +++ b/src/runtime/src/libraries/System.Net.Security/src/System/Net/CertificateValidationPal.OSX.cs @@ -10,41 +10,14 @@ namespace System.Net internal static partial class CertificateValidationPal { internal static SslPolicyErrors VerifyCertificateProperties( - SafeDeleteContext securityContext, + SafeDeleteContext? _ /*securityContext*/, X509Chain chain, - X509Certificate2? remoteCertificate, + X509Certificate2 remoteCertificate, bool checkCertName, bool isServer, string? hostName) { - SslPolicyErrors errors = SslPolicyErrors.None; - - if (remoteCertificate == null) - { - errors |= SslPolicyErrors.RemoteCertificateNotAvailable; - } - else - { - if (!chain.Build(remoteCertificate)) - { - errors |= SslPolicyErrors.RemoteCertificateChainErrors; - } - - if (!isServer && checkCertName) - { - SafeDeleteSslContext sslContext = (SafeDeleteSslContext)securityContext; - - if (!Interop.AppleCrypto.SslCheckHostnameMatch(sslContext.SslContext, hostName!, remoteCertificate.NotBefore, out int osStatus)) - { - errors |= SslPolicyErrors.RemoteCertificateNameMismatch; - - if (NetEventSource.Log.IsEnabled()) - NetEventSource.Error(sslContext, $"Cert name validation for '{hostName}' failed with status '{osStatus}'"); - } - } - } - - return errors; + return CertificateValidation.BuildChainAndVerifyProperties(chain, remoteCertificate, checkCertName, isServer, hostName, Span.Empty); } private static X509Certificate2? GetRemoteCertificate( diff --git a/src/runtime/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs b/src/runtime/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs index a510fedaf47..7bbd1359d04 100644 --- a/src/runtime/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs +++ b/src/runtime/src/libraries/System.Net.Security/tests/FunctionalTests/SslStreamSniTest.cs @@ -378,7 +378,7 @@ public static IEnumerable HostNameData() yield return new object[] { "test" }; // max allowed hostname length is 63 yield return new object[] { new string('a', 63) }; - yield return new object[] { "\u017C\u00F3\u0142\u0107 g\u0119\u015Bl\u0105 ja\u017A\u0144. \u7EA2\u70E7. \u7167\u308A\u713C\u304D" }; + yield return new object[] { "\u017C\u00F3\u0142\u0107g\u0119\u015Bl\u0105ja\u017A\u0144.\u7EA2\u70E7.\u7167\u308A\u713C\u304D" }; } } } diff --git a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs index ba8aa0aff49..fb08996f02f 100644 --- a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs +++ b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.Tasks.cs @@ -97,33 +97,7 @@ public ValueTask ConnectAsync(EndPoint remoteEP, CancellationToken cancellationT saea.RemoteEndPoint = remoteEP; - ValueTask connectTask = saea.ConnectAsync(this, saeaCancelable: cancellationToken.CanBeCanceled); - if (connectTask.IsCompleted || !cancellationToken.CanBeCanceled) - { - // Avoid async invocation overhead - return connectTask; - } - else - { - return WaitForConnectWithCancellation(saea, connectTask, cancellationToken); - } - - static async ValueTask WaitForConnectWithCancellation(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken) - { - Debug.Assert(cancellationToken.CanBeCanceled); - try - { - using (cancellationToken.UnsafeRegister(o => CancelConnectAsync((SocketAsyncEventArgs)o!), saea)) - { - await connectTask.ConfigureAwait(false); - } - } - catch (SocketException se) when (se.SocketErrorCode == SocketError.OperationAborted) - { - cancellationToken.ThrowIfCancellationRequested(); - throw; - } - } + return saea.ConnectAsync(this, cancellationToken); } /// @@ -1210,12 +1184,13 @@ public ValueTask SendToAsync(Socket socket, CancellationToken cancellationT ValueTask.FromException(CreateException(error)); } - public ValueTask ConnectAsync(Socket socket, bool saeaCancelable) + public ValueTask ConnectAsync(Socket socket, CancellationToken cancellationToken) { try { - if (socket.ConnectAsync(this, userSocket: true, saeaCancelable: saeaCancelable)) + if (socket.ConnectAsync(this, userSocket: true, saeaMultiConnectCancelable: false, cancellationToken)) { + _cancellationToken = cancellationToken; return new ValueTask(this, _mrvtsc.Version); } } diff --git a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs index bd7ba1a90b7..369860de37b 100644 --- a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs +++ b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/Socket.cs @@ -2875,11 +2875,14 @@ private bool AcceptAsync(SocketAsyncEventArgs e, CancellationToken cancellationT } public bool ConnectAsync(SocketAsyncEventArgs e) => - ConnectAsync(e, userSocket: true, saeaCancelable: true); + ConnectAsync(e, userSocket: true, saeaMultiConnectCancelable: true); - internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaCancelable) + internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaMultiConnectCancelable, CancellationToken cancellationToken = default) { - bool pending; + // saeaMultiConnectCancelable == true means that this method is being called by a SocketAsyncEventArgs-based top level API. + // In such cases, SocketAsyncEventArgs.StartOperationConnect() will set up an internal cancellation token (_multipleConnectCancellation) + // to support cancelling DNS multi-connect for Socket.CancelConnectAsync(). + Debug.Assert(!saeaMultiConnectCancelable || cancellationToken == default); ThrowIfDisposed(); @@ -2901,6 +2904,7 @@ internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaCan EndPoint? endPointSnapshot = e.RemoteEndPoint; DnsEndPoint? dnsEP = endPointSnapshot as DnsEndPoint; + bool pending; if (dnsEP != null) { if (NetEventSource.Log.IsEnabled()) NetEventSource.ConnectedAsyncDns(this); @@ -2911,10 +2915,10 @@ internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaCan } e.StartOperationCommon(this, SocketAsyncOperation.Connect); - e.StartOperationConnect(saeaCancelable, userSocket); + e.StartOperationConnect(saeaMultiConnectCancelable, userSocket); try { - pending = e.DnsConnectAsync(dnsEP, default, default); + pending = e.DnsConnectAsync(dnsEP, default, default, cancellationToken); } catch { @@ -2957,8 +2961,8 @@ internal bool ConnectAsync(SocketAsyncEventArgs e, bool userSocket, bool saeaCan // ConnectEx supports connection-oriented sockets but not UDS. The socket must be bound before calling ConnectEx. bool canUseConnectEx = _socketType == SocketType.Stream && endPointSnapshot.AddressFamily != AddressFamily.Unix; SocketError socketError = canUseConnectEx ? - e.DoOperationConnectEx(this, _handle) : - e.DoOperationConnect(_handle); // For connectionless protocols, Connect is not an I/O call. + e.DoOperationConnectEx(this, _handle, cancellationToken) : + e.DoOperationConnect(_handle, cancellationToken); // For connectionless protocols, Connect is not an I/O call. pending = socketError == SocketError.IOPending; } catch (Exception ex) @@ -3001,7 +3005,7 @@ public static bool ConnectAsync(SocketType socketType, ProtocolType protocolType e.StartOperationConnect(saeaMultiConnectCancelable: true, userSocket: false); try { - pending = e.DnsConnectAsync(dnsEP, socketType, protocolType); + pending = e.DnsConnectAsync(dnsEP, socketType, protocolType, cancellationToken: default); } catch { @@ -3012,7 +3016,7 @@ public static bool ConnectAsync(SocketType socketType, ProtocolType protocolType else { Socket attemptSocket = new Socket(endPointSnapshot.AddressFamily, socketType, protocolType); - pending = attemptSocket.ConnectAsync(e, userSocket: false, saeaCancelable: true); + pending = attemptSocket.ConnectAsync(e, userSocket: false, saeaMultiConnectCancelable: true); } return pending; diff --git a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs index c517bb70fc4..a5527972a43 100644 --- a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs +++ b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncContext.Unix.cs @@ -1536,7 +1536,7 @@ public SocketError Connect(Memory socketAddress) return operation.ErrorCode; } - public SocketError ConnectAsync(Memory socketAddress, Action, SocketFlags, SocketError> callback, Memory buffer, out int sentBytes) + public SocketError ConnectAsync(Memory socketAddress, Action, SocketFlags, SocketError> callback, Memory buffer, out int sentBytes, CancellationToken cancellationToken) { Debug.Assert(socketAddress.Length > 0, $"Unexpected socketAddressLen: {socketAddress.Length}"); Debug.Assert(callback != null, "Expected non-null callback"); @@ -1574,7 +1574,7 @@ public SocketError ConnectAsync(Memory socketAddress, Action socket CompletionCallback(bytesTransferred, SocketFlags.None, socketError); } - internal SocketError DoOperationConnectEx(Socket _ /*socket*/, SafeSocketHandle handle) + internal SocketError DoOperationConnectEx(Socket _ /*socket*/, SafeSocketHandle handle, CancellationToken cancellationToken) { - SocketError socketError = handle.AsyncContext.ConnectAsync(_socketAddress!.Buffer, ConnectCompletionCallback, _buffer.Slice(_offset, _count), out int sentBytes); + SocketError socketError = handle.AsyncContext.ConnectAsync(_socketAddress!.Buffer, ConnectCompletionCallback, _buffer.Slice(_offset, _count), out int sentBytes, cancellationToken); if (socketError != SocketError.IOPending) { FinishOperationSync(socketError, sentBytes, SocketFlags.None); @@ -81,9 +81,9 @@ internal SocketError DoOperationConnectEx(Socket _ /*socket*/, SafeSocketHandle return socketError; } - internal SocketError DoOperationConnect(SafeSocketHandle handle) + internal SocketError DoOperationConnect(SafeSocketHandle handle, CancellationToken cancellationToken) { - SocketError socketError = handle.AsyncContext.ConnectAsync(_socketAddress!.Buffer, ConnectCompletionCallback, Memory.Empty, out int _); + SocketError socketError = handle.AsyncContext.ConnectAsync(_socketAddress!.Buffer, ConnectCompletionCallback, Memory.Empty, out int _, cancellationToken); if (socketError != SocketError.IOPending) { FinishOperationSync(socketError, 0, SocketFlags.None); diff --git a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs index c98d0cede11..a764b070544 100644 --- a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs +++ b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.Windows.cs @@ -285,7 +285,9 @@ internal unsafe SocketError DoOperationAccept(Socket socket, SafeSocketHandle ha } } - internal SocketError DoOperationConnect(SafeSocketHandle handle) +#pragma warning disable IDE0060 + internal SocketError DoOperationConnect(SafeSocketHandle handle, CancellationToken cancellationToken) +#pragma warning restore IDE0060 { // Called for connectionless protocols. SocketError socketError = SocketPal.Connect(handle, _socketAddress!.Buffer); @@ -293,7 +295,7 @@ internal SocketError DoOperationConnect(SafeSocketHandle handle) return socketError; } - internal unsafe SocketError DoOperationConnectEx(Socket socket, SafeSocketHandle handle) + internal unsafe SocketError DoOperationConnectEx(Socket socket, SafeSocketHandle handle, CancellationToken cancellationToken) { Debug.Assert(_asyncCompletionOwnership == 0, $"Expected 0, got {_asyncCompletionOwnership}"); @@ -313,7 +315,7 @@ internal unsafe SocketError DoOperationConnectEx(Socket socket, SafeSocketHandle out int bytesTransferred, overlapped); - return ProcessIOCPResult(success, bytesTransferred, ref overlapped, _buffer, cancellationToken: default); + return ProcessIOCPResult(success, bytesTransferred, ref overlapped, _buffer, cancellationToken); } catch when (overlapped is not null) { diff --git a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs index 97f0d016b9d..ac90675f515 100644 --- a/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs +++ b/src/runtime/src/libraries/System.Net.Sockets/src/System/Net/Sockets/SocketAsyncEventArgs.cs @@ -676,14 +676,20 @@ internal void FinishOperationAsyncFailure(SocketError socketError, int bytesTran /// The DNS end point to which to connect. /// The SocketType to use to construct new sockets, if necessary. /// The ProtocolType to use to construct new sockets, if necessary. + /// The CancellationToken. /// true if the operation is pending; otherwise, false if it's already completed. - internal bool DnsConnectAsync(DnsEndPoint endPoint, SocketType socketType, ProtocolType protocolType) + internal bool DnsConnectAsync(DnsEndPoint endPoint, SocketType socketType, ProtocolType protocolType, CancellationToken cancellationToken) { Debug.Assert(endPoint.AddressFamily == AddressFamily.Unspecified || endPoint.AddressFamily == AddressFamily.InterNetwork || endPoint.AddressFamily == AddressFamily.InterNetworkV6); - CancellationToken cancellationToken = _multipleConnectCancellation?.Token ?? default; + if (_multipleConnectCancellation is not null) + { + Debug.Assert(!cancellationToken.CanBeCanceled, "Task-based connect logic should not use _multipleConnectCancellation for cancellation."); + // We registered a CancellationTokenSource in StartOperationConnect. + cancellationToken = _multipleConnectCancellation.Token; + } // In .NET 5 and earlier, the APM implementation allowed for synchronous exceptions from this to propagate // synchronously. This call is made here rather than in the Core async method below to preserve that behavior. @@ -774,12 +780,9 @@ async Task Core(MultiConnectSocketAsyncEventArgs internalArgs, Task } // Issue the connect. If it pends, wait for it to complete. - if (attemptSocket.ConnectAsync(internalArgs)) + if (attemptSocket.ConnectAsync(internalArgs, userSocket: true, saeaMultiConnectCancelable: false, cancellationToken)) { - using (cancellationToken.UnsafeRegister(s => Socket.CancelConnectAsync((SocketAsyncEventArgs)s!), internalArgs)) - { - await new ValueTask(internalArgs, internalArgs.Version).ConfigureAwait(false); - } + await new ValueTask(internalArgs, internalArgs.Version).ConfigureAwait(false); } // If it completed successfully, we're done; cleanup will be handled by the finally. diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml b/src/runtime/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml index c0523c4d646..39fc710bc49 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/ILLink/ILLink.Suppressions.LibraryBuild.xml @@ -29,5 +29,12 @@ M:System.ComponentModel.DefaultValueAttribute.#ctor(System.Type,System.String) This warning is left in the product so developers get an ILLink warning when trimming an app with System.ComponentModel.DefaultValueAttribute.IsSupported=true. + + ILLink + IL2067 + member + M:System.ComponentModel.DefaultValueAttribute.#ctor(System.Type,System.String) + This warning is left in the product so developers get an ILLink warning when trimming an app with System.ComponentModel.DefaultValueAttribute.IsSupported=true. + diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs index c890bbed83c..c103bd8fe43 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/Dictionary.cs @@ -409,7 +409,8 @@ internal ref TValue FindValue(TKey key) if (typeof(TKey).IsValueType && // comparer can only be null for value types; enable JIT to eliminate entire if block for ref types comparer == null) { - uint hashCode = (uint)key.GetHashCode(); + // TODO: Replace with just key.GetHashCode once https://github.com/dotnet/runtime/issues/117521 is resolved. + uint hashCode = (uint)EqualityComparer.Default.GetHashCode(key); int i = GetBucket(hashCode); Entry[]? entries = _entries; uint collisionCount = 0; diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs index 9bc99f7ef4c..ff903b17f07 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/NonRandomizedStringEqualityComparer.cs @@ -112,7 +112,7 @@ internal OrdinalIgnoreCaseComparer(IEqualityComparer wrappedComparer) : { } - public override bool Equals(string? x, string? y) => string.EqualsOrdinalIgnoreCase(x, y); + public override bool Equals(string? x, string? y) => string.Equals(x, y, StringComparison.OrdinalIgnoreCase); public override int GetHashCode(string? obj) { diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs index d6d79bb96b9..e613eb8614d 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Collections/Generic/RandomizedStringEqualityComparer.cs @@ -102,7 +102,7 @@ internal OrdinalIgnoreCaseComparer(IEqualityComparer wrappedComparer) string IAlternateEqualityComparer, string?>.Create(ReadOnlySpan span) => span.ToString(); - public override bool Equals(string? x, string? y) => string.EqualsOrdinalIgnoreCase(x, y); + public override bool Equals(string? x, string? y) => string.Equals(x, y, StringComparison.OrdinalIgnoreCase); bool IAlternateEqualityComparer, string?>.Equals(ReadOnlySpan alternate, string? other) { diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs index d10102a1507..12a04b63a5c 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/ComponentModel/DefaultValueAttribute.cs @@ -33,7 +33,7 @@ public class DefaultValueAttribute : Attribute /// culture as the translation context. /// public DefaultValueAttribute( - [DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] Type type, + Type type, string? value) { // The null check and try/catch here are because attributes should never throw exceptions. diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs index 5cabd72975e..c114427965f 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Diagnostics/CodeAnalysis/DynamicallyAccessedMemberTypes.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.ComponentModel; + namespace System.Diagnostics.CodeAnalysis { /// @@ -165,6 +167,7 @@ enum DynamicallyAccessedMemberTypes /// /// Specifies all members. /// + [EditorBrowsable(EditorBrowsableState.Never)] All = ~None } } diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs index c607bbb05d5..9df46043178 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/InteropServices/ComWrappers.cs @@ -314,15 +314,22 @@ public int QueryInterface(in Guid riid, out IntPtr ppvObject) } else { - Guid riidLocal = riid; - switch (customQueryInterface.GetInterface(ref riidLocal, out ppvObject)) + try { - case CustomQueryInterfaceResult.Handled: - return HResults.S_OK; - case CustomQueryInterfaceResult.NotHandled: - break; - case CustomQueryInterfaceResult.Failed: - return HResults.COR_E_INVALIDCAST; + Guid riidLocal = riid; + switch (customQueryInterface.GetInterface(ref riidLocal, out ppvObject)) + { + case CustomQueryInterfaceResult.Handled: + return HResults.S_OK; + case CustomQueryInterfaceResult.NotHandled: + break; + case CustomQueryInterfaceResult.Failed: + return HResults.COR_E_INVALIDCAST; + } + } + catch (Exception ex) + { + return Marshal.GetHRForException(ex); } } } diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs index f909cd61615..d725b3d06f6 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.PlatformNotSupported.cs @@ -473,6 +473,85 @@ internal Arm64() { } /// public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Rounding add narrow high part (bottom) + + /// + /// svuint8_t svraddhnb[_u16](svuint16_t op1, svuint16_t op2) + /// RADDHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svraddhnb[_s32](svint32_t op1, svint32_t op2) + /// RADDHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svraddhnb[_s64](svint64_t op1, svint64_t op2) + /// RADDHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svraddhnb[_s16](svint16_t op1, svint16_t op2) + /// RADDHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svraddhnb[_u32](svuint32_t op1, svuint32_t op2) + /// RADDHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svraddhnb[_u64](svuint64_t op1, svuint64_t op2) + /// RADDHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Rounding add narrow high part (top) + + /// + /// svuint8_t svraddhnt[_u16](svuint8_t even, svuint16_t op1, svuint16_t op2) + /// RADDHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svraddhnt[_s32](svint16_t even, svint32_t op1, svint32_t op2) + /// RADDHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svraddhnt[_s64](svint32_t even, svint64_t op1, svint64_t op2) + /// RADDHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svraddhnt[_s16](svint8_t even, svint16_t op1, svint16_t op2) + /// RADDHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svraddhnt[_u32](svuint16_t even, svuint32_t op1, svuint32_t op2) + /// RADDHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svraddhnt[_u64](svuint32_t even, svuint64_t op1, svuint64_t op2) + /// RADDHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Saturating add /// @@ -1166,6 +1245,58 @@ internal Arm64() { } /// public static Vector FusedSubtractHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Rounding halving add + + /// + /// svuint8_t svrhadd[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// URHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svrhadd[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// SRHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svrhadd[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// SRHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svrhadd[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// SRHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svrhadd[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// SRHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svrhadd[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// URHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svrhadd[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// URHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svrhadd[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// URHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// Interleaving Xor /// @@ -1265,6 +1396,546 @@ internal Arm64() { } public static Vector InterleavingXorOddEven(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + // Multiply-add, addend first + + /// + /// svint16_t svmla_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// MLA Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmla_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// MLA Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmla_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// MLA Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmla_lane[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// MLA Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmla_lane[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// MLA Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmla_lane[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3, uint64_t imm_index) + /// MLA Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply-add long (bottom) + + /// + /// svint16_t svmlalb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLALB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlalb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLALB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlalb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLALB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmlalb[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLALB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlalb[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLALB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlalb[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLALB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlalb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLALB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlalb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLALB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlalb_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLALB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlalb_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLALB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply-add long (top) + + /// + /// svint16_t svmlalt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLALT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlalt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLALT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlalt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLALT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmlalt[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLALT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlalt[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLALT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlalt[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLALT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlalt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLALT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlalt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLALT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlalt_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLALT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlalt_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLALT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply + + /// + /// svint16_t svmul_lane[_s16](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// MUL Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmul_lane[_s32](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// MUL Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmul_lane[_s64](svint64_t op1, svint64_t op2, uint64_t imm_index) + /// MUL Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmul_lane[_u16](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// MUL Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmul_lane[_u32](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// MUL Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmul_lane[_u64](svuint64_t op1, svuint64_t op2, uint64_t imm_index) + /// MUL Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply-subtract, minuend first + + /// + /// svint16_t svmls_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// MLS Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmls_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// MLS Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmls_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// MLS Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmls_lane[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// MLS Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmls_lane[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// MLS Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmls_lane[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3, uint64_t imm_index) + /// MLS Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply-subtract long (bottom) + + /// + /// svint16_t svmlslb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLSLB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlslb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLSLB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlslb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLSLB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmlslb[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLSLB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlslb[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLSLB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlslb[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLSLB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlslb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLSLB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlslb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLSLB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlslb_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLSLB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlslb_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLSLB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply-subtract long (top) + + /// + /// svint16_t svmlslt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLSLT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlslt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLSLT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlslt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLSLT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmlslt[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLSLT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlslt[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLSLT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlslt[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLSLT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmlslt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLSLT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmlslt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLSLT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmlslt_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLSLT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmlslt_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLSLT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply long (bottom) + + /// + /// svint16_t svmullb[_s16](svint8_t op1, svint8_t op2) + /// SMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmullb[_s32](svint16_t op1, svint16_t op2) + /// SMULLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmullb[_s64](svint32_t op1, svint32_t op2) + /// SMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmullb[_u16](svuint8_t op1, svuint8_t op2) + /// UMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmullb[_u32](svuint16_t op1, svuint16_t op2) + /// UMULLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmullb[_u64](svuint32_t op1, svuint32_t op2) + /// UMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmullb_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SMULLB Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmullb_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SMULLB Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmullb_lane[_u32](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// UMULLB Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmullb_lane[_u64](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// UMULLB Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Multiply long (top) + + /// + /// svint16_t svmullt[_s16](svint8_t op1, svint8_t op2) + /// SMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmullt[_s32](svint16_t op1, svint16_t op2) + /// SMULLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmullt[_s64](svint32_t op1, svint32_t op2) + /// SMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svmullt[_u16](svuint8_t op1, svuint8_t op2) + /// UMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmullt[_u32](svuint16_t op1, svuint16_t op2) + /// UMULLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmullt[_u64](svuint32_t op1, svuint32_t op2) + /// UMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svmullt_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SMULLT Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svint64_t svmullt_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SMULLT Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svmullt_lane[_u32](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// UMULLT Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svmullt_lane[_u64](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// UMULLT Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) { throw new PlatformNotSupportedException(); } + + + // Polynomial multiply + + /// + /// svuint8_t svpmul[_u8](svuint8_t op1, svuint8_t op2) + /// PMUL Zresult.B, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint8_t svpmul[_u8](svuint8_t op1, svuint8_t op2) + /// PMUL Zresult.B, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiply(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Polynomial multiply long (bottom) + + /// + /// svuint16_t svpmullb[_u16](svuint8_t op1, svuint8_t op2) + /// PMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svpmullb[_u64](svuint32_t op1, svuint32_t op2) + /// PMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector PolynomialMultiplyWideningEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Polynomial multiply long (top) + + /// + /// svuint16_t svpmullt[_u16](svuint8_t op1, svuint8_t op2) + /// PMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svpmullt[_u64](svuint32_t op1, svuint32_t op2) + /// PMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector PolynomialMultiplyWideningOdd(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Rounding shift left /// @@ -2198,6 +2869,36 @@ internal Arm64() { } public static Vector ShiftRightLogicalRoundedNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) { throw new PlatformNotSupportedException(); } + // Subtract with borrow long (bottom) + + /// + /// svuint32_t svsbclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// SBCLB Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector SubtractBorrowWideningEven(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svsbclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// SBCLB Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector SubtractBorrowWideningEven(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + + + // Subtract with borrow long (top) + + /// + /// svuint32_t svsbclt[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// SBCLT Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector SubtractBorrowWideningOdd(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + + /// + /// svuint64_t svsbclt[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// SBCLT Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector SubtractBorrowWideningOdd(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } + + // Subtract narrow high part (bottom) /// @@ -2276,6 +2977,84 @@ internal Arm64() { } public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + // Rounding subtract narrow high part (bottom) + + /// + /// svuint8_t svrsubhnb[_u16](svuint16_t op1, svuint16_t op2) + /// RSUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svrsubhnb[_s32](svint32_t op1, svint32_t op2) + /// RSUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svrsubhnb[_s64](svint64_t op1, svint64_t op2) + /// RSUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svrsubhnb[_s16](svint16_t op1, svint16_t op2) + /// RSUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svrsubhnb[_u32](svuint32_t op1, svuint32_t op2) + /// RSUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svrsubhnb[_u64](svuint64_t op1, svuint64_t op2) + /// RSUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + + // Rounding subtract narrow high part (top) + + /// + /// svuint8_t svrsubhnt[_u16](svuint8_t even, svuint16_t op1, svuint16_t op2) + /// RSUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint16_t svrsubhnt[_s32](svint16_t even, svint32_t op1, svint32_t op2) + /// RSUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint32_t svrsubhnt[_s64](svint32_t even, svint64_t op1, svint64_t op2) + /// RSUBHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svint8_t svrsubhnt[_s16](svint8_t even, svint16_t op1, svint16_t op2) + /// RSUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint16_t svrsubhnt[_u32](svuint16_t even, svuint32_t op1, svuint32_t op2) + /// RSUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + /// + /// svuint32_t svrsubhnt[_u64](svuint32_t even, svuint64_t op1, svuint64_t op2) + /// RSUBHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) { throw new PlatformNotSupportedException(); } + + // Saturating subtract /// @@ -2367,97 +3146,6 @@ internal Arm64() { } public static new Vector SubtractSaturate(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - // Saturating subtract reversed - - /// - /// svuint8_t svqsubr[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// svuint8_t svqsubr[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// svuint8_t svqsubr[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// UQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// UQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// UQSUB Ztied2.B, Pg/M, Ztied2.B, Zop1.B - /// UQSUB Zresult.B, Zop2.B, Zop1.B - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svint16_t svqsubr[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) - /// svint16_t svqsubr[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) - /// svint16_t svqsubr[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) - /// SQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// SQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// SQSUB Ztied2.H, Pg/M, Ztied2.H, Zop1.H - /// SQSUB Zresult.H, Zop2.H, Zop1.H - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svint32_t svqsubr[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) - /// svint32_t svqsubr[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) - /// svint32_t svqsubr[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) - /// SQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// SQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// SQSUB Ztied2.S, Pg/M, Ztied2.S, Zop1.S - /// SQSUB Zresult.S, Zop2.S, Zop1.S - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svint64_t svqsubr[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) - /// svint64_t svqsubr[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) - /// svint64_t svqsubr[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) - /// SQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// SQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// SQSUB Ztied2.D, Pg/M, Ztied2.D, Zop1.D - /// SQSUB Zresult.D, Zop2.D, Zop1.D - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svint8_t svqsubr[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) - /// svint8_t svqsubr[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) - /// svint8_t svqsubr[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) - /// SQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// SQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// SQSUB Ztied2.B, Pg/M, Ztied2.B, Zop1.B - /// SQSUB Zresult.B, Zop2.B, Zop1.B - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svuint16_t svqsubr[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// svuint16_t svqsubr[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// svuint16_t svqsubr[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// UQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// UQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// UQSUB Ztied2.H, Pg/M, Ztied2.H, Zop1.H - /// UQSUB Zresult.H, Zop2.H, Zop1.H - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svuint32_t svqsubr[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// svuint32_t svqsubr[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// svuint32_t svqsubr[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// UQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// UQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// UQSUB Ztied2.S, Pg/M, Ztied2.S, Zop1.S - /// UQSUB Zresult.S, Zop2.S, Zop1.S - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svqsubr[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// svuint64_t svqsubr[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// svuint64_t svqsubr[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// UQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// UQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// UQSUB Ztied2.D, Pg/M, Ztied2.D, Zop1.D - /// UQSUB Zresult.D, Zop2.D, Zop1.D - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - - // Subtract wide (bottom) /// @@ -2656,36 +3344,6 @@ internal Arm64() { } public static Vector SubtractWideningOddEven(Vector left, Vector right) { throw new PlatformNotSupportedException(); } - // Subtract with borrow long (bottom) - - /// - /// svuint32_t svsbclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) - /// SBCLB Ztied1.S, Zop2.S, Zop3.S - /// - public static Vector SubtractWithBorrowWideningLower(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svsbclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) - /// SBCLB Ztied1.D, Zop2.D, Zop3.D - /// - public static Vector SubtractWithBorrowWideningLower(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } - - - // Subtract with borrow long (top) - - /// - /// svuint32_t svsbclt[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) - /// SBCLT Ztied1.S, Zop2.S, Zop3.S - /// - public static Vector SubtractWithBorrowWideningUpper(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } - - /// - /// svuint64_t svsbclt[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) - /// SBCLT Ztied1.D, Zop2.D, Zop3.D - /// - public static Vector SubtractWithBorrowWideningUpper(Vector op1, Vector op2, Vector op3) { throw new PlatformNotSupportedException(); } - - // Bit vector table lookups /// diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs index bab0e4e55dd..542c142c54c 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Arm/Sve2.cs @@ -473,6 +473,84 @@ internal Arm64() { } public static Vector AddPairwiseWideningAndAdd(Vector left, Vector right) => AddPairwiseWideningAndAdd(left, right); + // Rounding add narrow high part (bottom) + + /// + /// svuint8_t svraddhnb[_u16](svuint16_t op1, svuint16_t op2) + /// RADDHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + /// + /// svint16_t svraddhnb[_s32](svint32_t op1, svint32_t op2) + /// RADDHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + /// + /// svint32_t svraddhnb[_s64](svint64_t op1, svint64_t op2) + /// RADDHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + /// + /// svint8_t svraddhnb[_s16](svint16_t op1, svint16_t op2) + /// RADDHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + /// + /// svuint16_t svraddhnb[_u32](svuint32_t op1, svuint32_t op2) + /// RADDHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + /// + /// svuint32_t svraddhnb[_u64](svuint64_t op1, svuint64_t op2) + /// RADDHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingEven(Vector left, Vector right) => AddRoundedHighNarrowingEven(left, right); + + + // Rounding add narrow high part (top) + + /// + /// svuint8_t svraddhnt[_u16](svuint8_t even, svuint16_t op1, svuint16_t op2) + /// RADDHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint16_t svraddhnt[_s32](svint16_t even, svint32_t op1, svint32_t op2) + /// RADDHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint32_t svraddhnt[_s64](svint32_t even, svint64_t op1, svint64_t op2) + /// RADDHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint8_t svraddhnt[_s16](svint8_t even, svint16_t op1, svint16_t op2) + /// RADDHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + /// + /// svuint16_t svraddhnt[_u32](svuint16_t even, svuint32_t op1, svuint32_t op2) + /// RADDHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + /// + /// svuint32_t svraddhnt[_u64](svuint32_t even, svuint64_t op1, svuint64_t op2) + /// RADDHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector AddRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => AddRoundedHighNarrowingOdd(even, left, right); + + // Saturating add /// @@ -1166,6 +1244,58 @@ internal Arm64() { } /// public static Vector FusedSubtractHalving(Vector left, Vector right) => FusedSubtractHalving(left, right); + + // Rounding halving add + + /// + /// svuint8_t svrhadd[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) + /// URHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svint16_t svrhadd[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) + /// SRHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svint32_t svrhadd[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) + /// SRHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svint64_t svrhadd[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) + /// SRHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svint8_t svrhadd[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) + /// SRHADD Ztied1.B, Pg/M, Ztied1.B, Zop2.B + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svuint16_t svrhadd[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) + /// URHADD Ztied1.H, Pg/M, Ztied1.H, Zop2.H + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svuint32_t svrhadd[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) + /// URHADD Ztied1.S, Pg/M, Ztied1.S, Zop2.S + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// + /// svuint64_t svrhadd[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) + /// URHADD Ztied1.D, Pg/M, Ztied1.D, Zop2.D + /// + public static Vector FusedAddRoundedHalving(Vector left, Vector right) => FusedAddRoundedHalving(left, right); + + /// Interleaving Xor /// @@ -1265,6 +1395,546 @@ internal Arm64() { } public static Vector InterleavingXorOddEven(Vector even, Vector left, Vector right) => InterleavingXorOddEven(even, left, right); + // Multiply-add, addend first + + /// + /// svint16_t svmla_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// MLA Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + /// + /// svint32_t svmla_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// MLA Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + /// + /// svint64_t svmla_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// MLA Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + /// + /// svuint16_t svmla_lane[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// MLA Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + /// + /// svuint32_t svmla_lane[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// MLA Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + /// + /// svuint64_t svmla_lane[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3, uint64_t imm_index) + /// MLA Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplyAddBySelectedScalar(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyAddBySelectedScalar(addend, left, right, rightIndex); + + + // Multiply-add long (bottom) + + /// + /// svint16_t svmlalb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLALB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svint32_t svmlalb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLALB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svint64_t svmlalb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLALB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svuint16_t svmlalb[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLALB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svuint32_t svmlalb[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLALB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svuint64_t svmlalb[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLALB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningEvenAndAdd(addend, left, right); + + /// + /// svint32_t svmlalb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLALB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndAdd(addend, left, right, rightIndex); + + /// + /// svint64_t svmlalb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLALB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndAdd(addend, left, right, rightIndex); + + /// + /// svuint32_t svmlalb_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLALB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndAdd(addend, left, right, rightIndex); + + /// + /// svuint64_t svmlalb_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLALB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndAdd(addend, left, right, rightIndex); + + + // Multiply-add long (top) + + /// + /// svint16_t svmlalt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLALT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svint32_t svmlalt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLALT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svint64_t svmlalt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLALT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svuint16_t svmlalt[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLALT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svuint32_t svmlalt[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLALT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svuint64_t svmlalt[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLALT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndAdd(Vector addend, Vector left, Vector right) => MultiplyWideningOddAndAdd(addend, left, right); + + /// + /// svint32_t svmlalt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLALT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndAdd(addend, left, right, rightIndex); + + /// + /// svint64_t svmlalt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLALT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndAdd(addend, left, right, rightIndex); + + /// + /// svuint32_t svmlalt_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLALT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndAdd(addend, left, right, rightIndex); + + /// + /// svuint64_t svmlalt_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLALT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndAdd(Vector addend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndAdd(addend, left, right, rightIndex); + + + // Multiply + + /// + /// svint16_t svmul_lane[_s16](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// MUL Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + /// + /// svint32_t svmul_lane[_s32](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// MUL Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + /// + /// svint64_t svmul_lane[_s64](svint64_t op1, svint64_t op2, uint64_t imm_index) + /// MUL Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + /// + /// svuint16_t svmul_lane[_u16](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// MUL Zresult.H, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + /// + /// svuint32_t svmul_lane[_u32](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// MUL Zresult.S, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + /// + /// svuint64_t svmul_lane[_u64](svuint64_t op1, svuint64_t op2, uint64_t imm_index) + /// MUL Zresult.D, Zop1.D, Zop2.D[imm_index] + /// + public static Vector MultiplyBySelectedScalar(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalar(left, right, rightIndex); + + + // Multiply-subtract, minuend first + + /// + /// svint16_t svmls_lane[_s16](svint16_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// MLS Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + /// + /// svint32_t svmls_lane[_s32](svint32_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// MLS Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + /// + /// svint64_t svmls_lane[_s64](svint64_t op1, svint64_t op2, svint64_t op3, uint64_t imm_index) + /// MLS Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + /// + /// svuint16_t svmls_lane[_u16](svuint16_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// MLS Ztied1.H, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + /// + /// svuint32_t svmls_lane[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// MLS Ztied1.S, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + /// + /// svuint64_t svmls_lane[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3, uint64_t imm_index) + /// MLS Ztied1.D, Zop2.D, Zop3.D[imm_index] + /// + public static Vector MultiplySubtractBySelectedScalar(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplySubtractBySelectedScalar(minuend, left, right, rightIndex); + + + // Multiply-subtract long (bottom) + + /// + /// svint16_t svmlslb[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLSLB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svint32_t svmlslb[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLSLB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svint64_t svmlslb[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLSLB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svuint16_t svmlslb[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLSLB Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svuint32_t svmlslb[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLSLB Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svuint64_t svmlslb[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLSLB Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningEvenAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningEvenAndSubtract(minuend, left, right); + + /// + /// svint32_t svmlslb_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLSLB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndSubtract(minuend, left, right, rightIndex); + + /// + /// svint64_t svmlslb_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLSLB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndSubtract(minuend, left, right, rightIndex); + + /// + /// svuint32_t svmlslb_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLSLB Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndSubtract(minuend, left, right, rightIndex); + + /// + /// svuint64_t svmlslb_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLSLB Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEvenAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEvenAndSubtract(minuend, left, right, rightIndex); + + + // Multiply-subtract long (top) + + /// + /// svint16_t svmlslt[_s16](svint16_t op1, svint8_t op2, svint8_t op3) + /// SMLSLT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svint32_t svmlslt[_s32](svint32_t op1, svint16_t op2, svint16_t op3) + /// SMLSLT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svint64_t svmlslt[_s64](svint64_t op1, svint32_t op2, svint32_t op3) + /// SMLSLT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svuint16_t svmlslt[_u16](svuint16_t op1, svuint8_t op2, svuint8_t op3) + /// UMLSLT Ztied1.H, Zop2.B, Zop3.B + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svuint32_t svmlslt[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3) + /// UMLSLT Ztied1.S, Zop2.H, Zop3.H + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svuint64_t svmlslt[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3) + /// UMLSLT Ztied1.D, Zop2.S, Zop3.S + /// + public static Vector MultiplyWideningOddAndSubtract(Vector minuend, Vector left, Vector right) => MultiplyWideningOddAndSubtract(minuend, left, right); + + /// + /// svint32_t svmlslt_lane[_s32](svint32_t op1, svint16_t op2, svint16_t op3, uint64_t imm_index) + /// SMLSLT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndSubtract(minuend, left, right, rightIndex); + + /// + /// svint64_t svmlslt_lane[_s64](svint64_t op1, svint32_t op2, svint32_t op3, uint64_t imm_index) + /// SMLSLT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndSubtract(minuend, left, right, rightIndex); + + /// + /// svuint32_t svmlslt_lane[_u32](svuint32_t op1, svuint16_t op2, svuint16_t op3, uint64_t imm_index) + /// UMLSLT Ztied1.S, Zop2.H, Zop3.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndSubtract(minuend, left, right, rightIndex); + + /// + /// svuint64_t svmlslt_lane[_u64](svuint64_t op1, svuint32_t op2, svuint32_t op3, uint64_t imm_index) + /// UMLSLT Ztied1.D, Zop2.S, Zop3.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOddAndSubtract(Vector minuend, Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOddAndSubtract(minuend, left, right, rightIndex); + + + // Multiply long (bottom) + + /// + /// svint16_t svmullb[_s16](svint8_t op1, svint8_t op2) + /// SMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svint32_t svmullb[_s32](svint16_t op1, svint16_t op2) + /// SMULLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svint64_t svmullb[_s64](svint32_t op1, svint32_t op2) + /// SMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svuint16_t svmullb[_u16](svuint8_t op1, svuint8_t op2) + /// UMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svuint32_t svmullb[_u32](svuint16_t op1, svuint16_t op2) + /// UMULLB Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svuint64_t svmullb[_u64](svuint32_t op1, svuint32_t op2) + /// UMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningEven(Vector left, Vector right) => MultiplyWideningEven(left, right); + + /// + /// svint32_t svmullb_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SMULLB Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEven(left, right, rightIndex); + + /// + /// svint64_t svmullb_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SMULLB Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEven(left, right, rightIndex); + + /// + /// svuint32_t svmullb_lane[_u32](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// UMULLB Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEven(left, right, rightIndex); + + /// + /// svuint64_t svmullb_lane[_u64](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// UMULLB Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningEven(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningEven(left, right, rightIndex); + + + // Multiply long (top) + + /// + /// svint16_t svmullt[_s16](svint8_t op1, svint8_t op2) + /// SMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svint32_t svmullt[_s32](svint16_t op1, svint16_t op2) + /// SMULLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svint64_t svmullt[_s64](svint32_t op1, svint32_t op2) + /// SMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svuint16_t svmullt[_u16](svuint8_t op1, svuint8_t op2) + /// UMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svuint32_t svmullt[_u32](svuint16_t op1, svuint16_t op2) + /// UMULLT Zresult.S, Zop1.H, Zop2.H + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svuint64_t svmullt[_u64](svuint32_t op1, svuint32_t op2) + /// UMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector MultiplyWideningOdd(Vector left, Vector right) => MultiplyWideningOdd(left, right); + + /// + /// svint32_t svmullt_lane[_s32](svint16_t op1, svint16_t op2, uint64_t imm_index) + /// SMULLT Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOdd(left, right, rightIndex); + + /// + /// svint64_t svmullt_lane[_s64](svint32_t op1, svint32_t op2, uint64_t imm_index) + /// SMULLT Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOdd(left, right, rightIndex); + + /// + /// svuint32_t svmullt_lane[_u32](svuint16_t op1, svuint16_t op2, uint64_t imm_index) + /// UMULLT Zresult.S, Zop1.H, Zop2.H[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOdd(left, right, rightIndex); + + /// + /// svuint64_t svmullt_lane[_u64](svuint32_t op1, svuint32_t op2, uint64_t imm_index) + /// UMULLT Zresult.D, Zop1.S, Zop2.S[imm_index] + /// + public static Vector MultiplyBySelectedScalarWideningOdd(Vector left, Vector right, [ConstantExpected] byte rightIndex) => MultiplyBySelectedScalarWideningOdd(left, right, rightIndex); + + + // Polynomial multiply + + /// + /// svuint8_t svpmul[_u8](svuint8_t op1, svuint8_t op2) + /// PMUL Zresult.B, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiply(Vector left, Vector right) => PolynomialMultiply(left, right); + + /// + /// svuint8_t svpmul[_u8](svuint8_t op1, svuint8_t op2) + /// PMUL Zresult.B, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiply(Vector left, Vector right) => PolynomialMultiply(left, right); + + + // Polynomial multiply long (bottom) + + /// + /// svuint16_t svpmullb[_u16](svuint8_t op1, svuint8_t op2) + /// PMULLB Zresult.H, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiplyWideningEven(Vector left, Vector right) => PolynomialMultiplyWideningEven(left, right); + + /// + /// svuint64_t svpmullb[_u64](svuint32_t op1, svuint32_t op2) + /// PMULLB Zresult.D, Zop1.S, Zop2.S + /// + public static Vector PolynomialMultiplyWideningEven(Vector left, Vector right) => PolynomialMultiplyWideningEven(left, right); + + + // Polynomial multiply long (top) + + /// + /// svuint16_t svpmullt[_u16](svuint8_t op1, svuint8_t op2) + /// PMULLT Zresult.H, Zop1.B, Zop2.B + /// + public static Vector PolynomialMultiplyWideningOdd(Vector left, Vector right) => PolynomialMultiplyWideningOdd(left, right); + + /// + /// svuint64_t svpmullt[_u64](svuint32_t op1, svuint32_t op2) + /// PMULLT Zresult.D, Zop1.S, Zop2.S + /// + public static Vector PolynomialMultiplyWideningOdd(Vector left, Vector right) => PolynomialMultiplyWideningOdd(left, right); + + // Rounding shift left /// @@ -2198,6 +2868,36 @@ internal Arm64() { } public static Vector ShiftRightLogicalRoundedNarrowingSaturateOdd(Vector even, Vector value, [ConstantExpected] byte count) => ShiftRightLogicalRoundedNarrowingSaturateOdd(even, value, count); + // Subtract with borrow long (bottom) + + /// + /// svuint32_t svsbclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// SBCLB Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector SubtractBorrowWideningEven(Vector op1, Vector op2, Vector op3) => SubtractBorrowWideningEven(op1, op2, op3); + + /// + /// svuint64_t svsbclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// SBCLB Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector SubtractBorrowWideningEven(Vector op1, Vector op2, Vector op3) => SubtractBorrowWideningEven(op1, op2, op3); + + + // Subtract with borrow long (top) + + /// + /// svuint32_t svsbclt[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) + /// SBCLT Ztied1.S, Zop2.S, Zop3.S + /// + public static Vector SubtractBorrowWideningOdd(Vector op1, Vector op2, Vector op3) => SubtractBorrowWideningOdd(op1, op2, op3); + + /// + /// svuint64_t svsbclt[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) + /// SBCLT Ztied1.D, Zop2.D, Zop3.D + /// + public static Vector SubtractBorrowWideningOdd(Vector op1, Vector op2, Vector op3) => SubtractBorrowWideningOdd(op1, op2, op3); + + // Subtract narrow high part (bottom) /// @@ -2276,6 +2976,84 @@ internal Arm64() { } public static Vector SubtractHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractHighNarrowingOdd(even, left, right); + // Rounding subtract narrow high part (bottom) + + /// + /// svuint8_t svrsubhnb[_u16](svuint16_t op1, svuint16_t op2) + /// RSUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + /// + /// svint16_t svrsubhnb[_s32](svint32_t op1, svint32_t op2) + /// RSUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + /// + /// svint32_t svrsubhnb[_s64](svint64_t op1, svint64_t op2) + /// RSUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + /// + /// svint8_t svrsubhnb[_s16](svint16_t op1, svint16_t op2) + /// RSUBHNB Zresult.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + /// + /// svuint16_t svrsubhnb[_u32](svuint32_t op1, svuint32_t op2) + /// RSUBHNB Zresult.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + /// + /// svuint32_t svrsubhnb[_u64](svuint64_t op1, svuint64_t op2) + /// RSUBHNB Zresult.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingEven(Vector left, Vector right) => SubtractRoundedHighNarrowingEven(left, right); + + + // Rounding subtract narrow high part (top) + + /// + /// svuint8_t svrsubhnt[_u16](svuint8_t even, svuint16_t op1, svuint16_t op2) + /// RSUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint16_t svrsubhnt[_s32](svint16_t even, svint32_t op1, svint32_t op2) + /// RSUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint32_t svrsubhnt[_s64](svint32_t even, svint64_t op1, svint64_t op2) + /// RSUBHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + /// + /// svint8_t svrsubhnt[_s16](svint8_t even, svint16_t op1, svint16_t op2) + /// RSUBHNT Ztied.B, Zop1.H, Zop2.H + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + /// + /// svuint16_t svrsubhnt[_u32](svuint16_t even, svuint32_t op1, svuint32_t op2) + /// RSUBHNT Ztied.H, Zop1.S, Zop2.S + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + /// + /// svuint32_t svrsubhnt[_u64](svuint32_t even, svuint64_t op1, svuint64_t op2) + /// RSUBHNT Ztied.S, Zop1.D, Zop2.D + /// + public static Vector SubtractRoundedHighNarrowingOdd(Vector even, Vector left, Vector right) => SubtractRoundedHighNarrowingOdd(even, left, right); + + // Saturating subtract /// @@ -2367,97 +3145,6 @@ internal Arm64() { } public static new Vector SubtractSaturate(Vector left, Vector right) => SubtractSaturate(left, right); - // Saturating subtract reversed - - /// - /// svuint8_t svqsubr[_u8]_m(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// svuint8_t svqsubr[_u8]_x(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// svuint8_t svqsubr[_u8]_z(svbool_t pg, svuint8_t op1, svuint8_t op2) - /// UQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// UQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// UQSUB Ztied2.B, Pg/M, Ztied2.B, Zop1.B - /// UQSUB Zresult.B, Zop2.B, Zop1.B - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svint16_t svqsubr[_s16]_m(svbool_t pg, svint16_t op1, svint16_t op2) - /// svint16_t svqsubr[_s16]_x(svbool_t pg, svint16_t op1, svint16_t op2) - /// svint16_t svqsubr[_s16]_z(svbool_t pg, svint16_t op1, svint16_t op2) - /// SQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// SQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// SQSUB Ztied2.H, Pg/M, Ztied2.H, Zop1.H - /// SQSUB Zresult.H, Zop2.H, Zop1.H - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svint32_t svqsubr[_s32]_m(svbool_t pg, svint32_t op1, svint32_t op2) - /// svint32_t svqsubr[_s32]_x(svbool_t pg, svint32_t op1, svint32_t op2) - /// svint32_t svqsubr[_s32]_z(svbool_t pg, svint32_t op1, svint32_t op2) - /// SQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// SQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// SQSUB Ztied2.S, Pg/M, Ztied2.S, Zop1.S - /// SQSUB Zresult.S, Zop2.S, Zop1.S - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svint64_t svqsubr[_s64]_m(svbool_t pg, svint64_t op1, svint64_t op2) - /// svint64_t svqsubr[_s64]_x(svbool_t pg, svint64_t op1, svint64_t op2) - /// svint64_t svqsubr[_s64]_z(svbool_t pg, svint64_t op1, svint64_t op2) - /// SQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// SQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// SQSUB Ztied2.D, Pg/M, Ztied2.D, Zop1.D - /// SQSUB Zresult.D, Zop2.D, Zop1.D - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svint8_t svqsubr[_s8]_m(svbool_t pg, svint8_t op1, svint8_t op2) - /// svint8_t svqsubr[_s8]_x(svbool_t pg, svint8_t op1, svint8_t op2) - /// svint8_t svqsubr[_s8]_z(svbool_t pg, svint8_t op1, svint8_t op2) - /// SQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// SQSUBR Ztied1.B, Pg/M, Ztied1.B, Zop2.B - /// SQSUB Ztied2.B, Pg/M, Ztied2.B, Zop1.B - /// SQSUB Zresult.B, Zop2.B, Zop1.B - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svuint16_t svqsubr[_u16]_m(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// svuint16_t svqsubr[_u16]_x(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// svuint16_t svqsubr[_u16]_z(svbool_t pg, svuint16_t op1, svuint16_t op2) - /// UQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// UQSUBR Ztied1.H, Pg/M, Ztied1.H, Zop2.H - /// UQSUB Ztied2.H, Pg/M, Ztied2.H, Zop1.H - /// UQSUB Zresult.H, Zop2.H, Zop1.H - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svuint32_t svqsubr[_u32]_m(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// svuint32_t svqsubr[_u32]_x(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// svuint32_t svqsubr[_u32]_z(svbool_t pg, svuint32_t op1, svuint32_t op2) - /// UQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// UQSUBR Ztied1.S, Pg/M, Ztied1.S, Zop2.S - /// UQSUB Ztied2.S, Pg/M, Ztied2.S, Zop1.S - /// UQSUB Zresult.S, Zop2.S, Zop1.S - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - /// - /// svuint64_t svqsubr[_u64]_m(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// svuint64_t svqsubr[_u64]_x(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// svuint64_t svqsubr[_u64]_z(svbool_t pg, svuint64_t op1, svuint64_t op2) - /// UQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// UQSUBR Ztied1.D, Pg/M, Ztied1.D, Zop2.D - /// UQSUB Ztied2.D, Pg/M, Ztied2.D, Zop1.D - /// UQSUB Zresult.D, Zop2.D, Zop1.D - /// - public static Vector SubtractSaturateReversed(Vector left, Vector right) => SubtractSaturateReversed(left, right); - - // Subtract wide (bottom) /// @@ -2656,36 +3343,6 @@ internal Arm64() { } public static Vector SubtractWideningOddEven(Vector left, Vector right) => SubtractWideningOddEven(left, right); - // Subtract with borrow long (bottom) - - /// - /// svuint32_t svsbclb[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) - /// SBCLB Ztied1.S, Zop2.S, Zop3.S - /// - public static Vector SubtractWithBorrowWideningLower(Vector op1, Vector op2, Vector op3) => SubtractWithBorrowWideningLower(op1, op2, op3); - - /// - /// svuint64_t svsbclb[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) - /// SBCLB Ztied1.D, Zop2.D, Zop3.D - /// - public static Vector SubtractWithBorrowWideningLower(Vector op1, Vector op2, Vector op3) => SubtractWithBorrowWideningLower(op1, op2, op3); - - - // Subtract with borrow long (top) - - /// - /// svuint32_t svsbclt[_u32](svuint32_t op1, svuint32_t op2, svuint32_t op3) - /// SBCLT Ztied1.S, Zop2.S, Zop3.S - /// - public static Vector SubtractWithBorrowWideningUpper(Vector op1, Vector op2, Vector op3) => SubtractWithBorrowWideningUpper(op1, op2, op3); - - /// - /// svuint64_t svsbclt[_u64](svuint64_t op1, svuint64_t op2, svuint64_t op3) - /// SBCLT Ztied1.D, Zop2.D, Zop3.D - /// - public static Vector SubtractWithBorrowWideningUpper(Vector op1, Vector op2, Vector op3) => SubtractWithBorrowWideningUpper(op1, op2, op3); - - // Bit vector table lookups /// diff --git a/src/runtime/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs b/src/runtime/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs index f9261106b34..458aa815cd6 100644 --- a/src/runtime/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs +++ b/src/runtime/src/libraries/System.Private.CoreLib/src/System/String.Comparison.cs @@ -46,26 +46,6 @@ ref Unsafe.Add(ref strA.GetRawStringData(), (nint)(uint)indexA /* force zero-ext ref Unsafe.Add(ref strB.GetRawStringData(), (nint)(uint)indexB /* force zero-extension */), countB); } - internal static bool EqualsOrdinalIgnoreCase(string? strA, string? strB) - { - if (ReferenceEquals(strA, strB)) - { - return true; - } - - if (strA is null || strB is null) - { - return false; - } - - if (strA.Length != strB.Length) - { - return false; - } - - return EqualsOrdinalIgnoreCaseNoLengthCheck(strA, strB); - } - private static bool EqualsOrdinalIgnoreCaseNoLengthCheck(string strA, string strB) { Debug.Assert(strA.Length == strB.Length); diff --git a/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs b/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs index 17378d29ec3..cc1757f072f 100644 --- a/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs +++ b/src/runtime/src/libraries/System.Runtime.Intrinsics/ref/System.Runtime.Intrinsics.cs @@ -6177,7 +6177,18 @@ internal Arm64() { } public static System.Numerics.Vector AddPairwiseWideningAndAdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddPairwiseWideningAndAdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector AddPairwiseWideningAndAdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector AddRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector AddSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6253,6 +6264,14 @@ internal Arm64() { } public static System.Numerics.Vector BitwiseSelectRightInverted(System.Numerics.Vector select, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector BitwiseSelectRightInverted(System.Numerics.Vector select, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector BitwiseSelectRightInverted(System.Numerics.Vector select, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector FusedAddRoundedHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector FusedAddHalving(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6285,6 +6304,90 @@ internal Arm64() { } public static System.Numerics.Vector InterleavingXorOddEven(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector InterleavingXorOddEven(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector InterleavingXorOddEven(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyAddBySelectedScalar(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalar(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEven(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEven(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEven(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEven(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyBySelectedScalarWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplySubtractBySelectedScalar(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right, [ConstantExpected] byte rightIndex) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningEvenAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndAdd(System.Numerics.Vector addend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector MultiplyWideningOddAndSubtract(System.Numerics.Vector minuend, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiply(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiplyWideningEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector PolynomialMultiplyWideningOdd(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector ShiftArithmeticRounded(System.Numerics.Vector value, System.Numerics.Vector count) { throw null; } public static System.Numerics.Vector ShiftArithmeticRounded(System.Numerics.Vector value, System.Numerics.Vector count) { throw null; } public static System.Numerics.Vector ShiftArithmeticRounded(System.Numerics.Vector value, System.Numerics.Vector count) { throw null; } @@ -6425,6 +6528,10 @@ internal Arm64() { } public static System.Numerics.Vector ShiftRightLogicalRoundedNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightLogicalRoundedNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } public static System.Numerics.Vector ShiftRightLogicalRoundedNarrowingSaturateOdd(System.Numerics.Vector even, System.Numerics.Vector value, [ConstantExpected] byte count) { throw null; } + public static System.Numerics.Vector SubtractBorrowWideningEven(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } + public static System.Numerics.Vector SubtractBorrowWideningEven(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } + public static System.Numerics.Vector SubtractBorrowWideningOdd(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } + public static System.Numerics.Vector SubtractBorrowWideningOdd(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } public static System.Numerics.Vector SubtractHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6437,14 +6544,18 @@ internal Arm64() { } public static System.Numerics.Vector SubtractHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractSaturateReversed(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } + public static System.Numerics.Vector SubtractRoundedHighNarrowingOdd(System.Numerics.Vector even, System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector SubtractSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector SubtractSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static new System.Numerics.Vector SubtractSaturate(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } @@ -6483,10 +6594,6 @@ internal Arm64() { } public static System.Numerics.Vector SubtractWideningOddEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractWideningOddEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } public static System.Numerics.Vector SubtractWideningOddEven(System.Numerics.Vector left, System.Numerics.Vector right) { throw null; } - public static System.Numerics.Vector SubtractWithBorrowWideningLower(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } - public static System.Numerics.Vector SubtractWithBorrowWideningLower(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } - public static System.Numerics.Vector SubtractWithBorrowWideningUpper(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } - public static System.Numerics.Vector SubtractWithBorrowWideningUpper(System.Numerics.Vector op1, System.Numerics.Vector op2, System.Numerics.Vector op3) { throw null; } public static System.Numerics.Vector VectorTableLookup((System.Numerics.Vector data1, System.Numerics.Vector data2) table, System.Numerics.Vector indices) { throw null; } public static System.Numerics.Vector VectorTableLookup((System.Numerics.Vector data1, System.Numerics.Vector data2) table, System.Numerics.Vector indices) { throw null; } public static System.Numerics.Vector VectorTableLookup((System.Numerics.Vector data1, System.Numerics.Vector data2) table, System.Numerics.Vector indices) { throw null; } diff --git a/src/runtime/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs b/src/runtime/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs index ff0f1b694c0..069cc8c481a 100644 --- a/src/runtime/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs +++ b/src/runtime/src/libraries/System.Runtime.Loader/tests/LoaderLinkTest.cs @@ -13,7 +13,7 @@ namespace LoaderLinkTest { public class LoaderLinkTest { - [Fact] + [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.HasAssemblyFiles))] public static void EnsureTypesLinked() // https://github.com/dotnet/runtime/issues/42207 { string parentDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); diff --git a/src/runtime/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs b/src/runtime/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs index 4f5e6265135..e00166fa0be 100644 --- a/src/runtime/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs +++ b/src/runtime/src/libraries/System.Runtime.Loader/tests/SatelliteAssemblies.cs @@ -74,7 +74,7 @@ public static IEnumerable MainResources_TestData() } } - [Theory] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.HasAssemblyFiles))] [MemberData(nameof(MainResources_TestData))] public static void mainResources(string lang, string expected) { @@ -131,7 +131,7 @@ public static IEnumerable DescribeLib_TestData() yield return new object[] { "ReferencedClassLibNeutralIsSatellite", "ReferencedClassLibNeutralIsSatellite.Program, ReferencedClassLibNeutralIsSatellite", "es", "Neutral (es) language ReferencedClassLibNeutralIsSatellite description 1.0.0" }; } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.HasAssemblyFiles))] [MemberData(nameof(DescribeLib_TestData))] public void describeLib(string alc, string type, string culture, string expected) { @@ -187,7 +187,7 @@ public static IEnumerable SatelliteLoadsCorrectly_TestData() yield return new object[] { "ReferencedClassLibNeutralIsSatellite", "ReferencedClassLibNeutralIsSatellite", "es" }; } - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.HasAssemblyFiles))] [MemberData(nameof(SatelliteLoadsCorrectly_TestData))] public void SatelliteLoadsCorrectly_FromName(string alc, string assemblyName, string culture) { @@ -207,8 +207,8 @@ public void SatelliteLoadsCorrectly_FromName(string alc, string assemblyName, st Assert.Equal(culture, satelliteAssembly.GetName().CultureName); } - - [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization))] + + [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotInvariantGlobalization), nameof(PlatformDetection.HasAssemblyFiles))] [MemberData(nameof(SatelliteLoadsCorrectly_TestData))] public void SatelliteLoadsCorrectly_FromPath(string alc, string assemblyName, string culture) { diff --git a/src/runtime/src/libraries/System.Runtime/ref/System.Runtime.cs b/src/runtime/src/libraries/System.Runtime/ref/System.Runtime.cs index 8ba41f11d65..e27c05b00e3 100644 --- a/src/runtime/src/libraries/System.Runtime/ref/System.Runtime.cs +++ b/src/runtime/src/libraries/System.Runtime/ref/System.Runtime.cs @@ -8552,7 +8552,7 @@ public DefaultValueAttribute(object? value) { } public DefaultValueAttribute(sbyte value) { } public DefaultValueAttribute(float value) { } public DefaultValueAttribute(string? value) { } - public DefaultValueAttribute([System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes.All)] System.Type type, string? value) { } + public DefaultValueAttribute(System.Type type, string? value) { } [System.CLSCompliantAttribute(false)] public DefaultValueAttribute(ushort value) { } [System.CLSCompliantAttribute(false)] @@ -8894,6 +8894,7 @@ public DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.Dynam [System.FlagsAttribute] public enum DynamicallyAccessedMemberTypes { + [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)] All = -1, None = 0, PublicParameterlessConstructor = 1, diff --git a/src/runtime/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs b/src/runtime/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs index 5e945c446a2..81bfc96492b 100644 --- a/src/runtime/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs +++ b/src/runtime/src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs @@ -3386,6 +3386,7 @@ public sealed partial class Pkcs12LoaderLimits { public Pkcs12LoaderLimits() { } public Pkcs12LoaderLimits(System.Security.Cryptography.X509Certificates.Pkcs12LoaderLimits copyFrom) { } + public bool AllowDuplicateAttributes { get { throw null; } set { } } public static System.Security.Cryptography.X509Certificates.Pkcs12LoaderLimits DangerousNoLimits { get { throw null; } } public static System.Security.Cryptography.X509Certificates.Pkcs12LoaderLimits Defaults { get { throw null; } } public bool IgnoreEncryptedAuthSafes { get { throw null; } set { } } diff --git a/src/runtime/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx b/src/runtime/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx index d6a1cb9bd20..88f15f22fa5 100644 --- a/src/runtime/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx +++ b/src/runtime/src/libraries/System.Security.Cryptography/src/Resources/Strings.resx @@ -411,6 +411,9 @@ The specified hash is not a valid size for this hash algorithm. + + HashML-DSA '{0}' cannot be used with hash algorithm '{1}'. + Hash must be finalized before the hash value is retrieved. diff --git a/src/runtime/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml b/src/runtime/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml index 24e10dd2564..a0d092eccf4 100644 --- a/src/runtime/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml +++ b/src/runtime/src/libraries/apicompat/ApiCompatBaseline.NetCoreAppLatestStable.xml @@ -229,6 +229,24 @@ net9.0/System.Runtime.Intrinsics.dll net10.0/System.Runtime.Intrinsics.dll + + CP0014 + M:System.ComponentModel.DefaultValueAttribute.#ctor(System.Type,System.String)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + net9.0/netstandard.dll + net10.0/netstandard.dll + + + CP0014 + M:System.ComponentModel.DefaultValueAttribute.#ctor(System.Type,System.String)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + net9.0/System.dll + net10.0/System.dll + + + CP0014 + M:System.ComponentModel.DefaultValueAttribute.#ctor(System.Type,System.String)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] + net9.0/System.Runtime.dll + net10.0/System.Runtime.dll + CP0015 M:System.Delegate.#ctor(System.Type,System.String)$0:[T:System.Diagnostics.CodeAnalysis.DynamicallyAccessedMembersAttribute] diff --git a/src/runtime/src/libraries/tests.proj b/src/runtime/src/libraries/tests.proj index a2b63c15130..4b6c7c027c1 100644 --- a/src/runtime/src/libraries/tests.proj +++ b/src/runtime/src/libraries/tests.proj @@ -226,16 +226,15 @@ - - - + + @@ -602,8 +601,7 @@ - - + diff --git a/src/runtime/src/mono/mono.proj b/src/runtime/src/mono/mono.proj index 2cb4ba6ffec..e0fa813eb20 100644 --- a/src/runtime/src/mono/mono.proj +++ b/src/runtime/src/mono/mono.proj @@ -953,6 +953,14 @@ JS_ENGINES = [NODE_JS] <_MonoAOTCFLAGSOption>-DCMAKE_C_FLAGS="@(_MonoAOTCPPFLAGS, ' ') @(_MonoAOTCFLAGS, ' ')" <_MonoAOTCXXFLAGSOption>-DCMAKE_CXX_FLAGS="@(_MonoAOTCPPFLAGS, ' ') @(_MonoAOTCXXFLAGS, ' ')" + + + <_PythonCmd Condition="'$(HostOS)' != 'windows'">python3 + <_PythonCmd Condition="'$(HostOS)' == 'windows'">python + + <_PythonCmd Condition="'$(HostOS)' == 'windows' and ('$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true')">$([MSBuild]::NormalizePath('$(PkgMicrosoft_NET_Runtime_Emscripten_3_1_56_Python_win-x64)', 'tools', 'python.exe')) + + @@ -975,15 +983,12 @@ JS_ENGINES = [NODE_JS] + <_MonoSkipInitCompiler Condition="'$(AotHostArchitecture)' != '$(BuildArchitecture)'">false <_MonoSkipInitCompiler Condition="'$(CrossBuild)' == 'true'">false - <_PythonCmd Condition="'$(HostOS)' != 'windows'">python3 - <_PythonCmd Condition="'$(HostOS)' == 'windows'">python - - <_PythonCmd Condition="'$(HostOS)' == 'windows' and ('$(TargetsBrowser)' == 'true' or '$(TargetsWasi)' == 'true')">$([MSBuild]::NormalizePath('$(PkgMicrosoft_NET_Runtime_Emscripten_3_1_56_Python_win-x64)', 'tools', 'python.exe')) <_MonoAotCrossOffsetsToolPath>$(MonoProjectRoot)mono\offsets\offsets-tool.py <_MonoAotCrossOffsetsCommand Condition="'$(MonoUseCrossTool)' == 'true'">$(_PythonCmd) $(_MonoAotCrossOffsetsToolPath) @(MonoAotCrossOffsetsToolParams, ' ') <_MonoAotCMakeConfigureCommand>cmake @(MonoAOTCMakeArgs, ' ') $(MonoCMakeExtraArgs) "$(MonoProjectRoot.TrimEnd('\/'))" diff --git a/src/runtime/src/mono/mono/mini/CMakeLists.txt b/src/runtime/src/mono/mono/mini/CMakeLists.txt index a2b3bdae9a7..23b8d15bf70 100644 --- a/src/runtime/src/mono/mono/mini/CMakeLists.txt +++ b/src/runtime/src/mono/mono/mini/CMakeLists.txt @@ -4,7 +4,7 @@ if(ENABLE_LLVM OR ENABLE_LLVM_RUNTIME OR HOST_BROWSER) enable_language(CXX) endif() -include(FindPython3) +include(FindPython) include_directories( ${PROJECT_BINARY_DIR}/ @@ -494,60 +494,60 @@ if(HOST_BROWSER OR HOST_WASI OR TARGET_WASM) install(TARGETS mono-wasm-nosimd LIBRARY) endif() -find_package(Python3 COMPONENTS Interpreter) +find_package(Python COMPONENTS Interpreter) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-amd64.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_AMD64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-amd64.h amd64_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-amd64.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_AMD64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-amd64.h amd64_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-amd64.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-amd64.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-x86.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_X86 ${CMAKE_CURRENT_SOURCE_DIR} cpu-x86.h x86_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-x86.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_X86 ${CMAKE_CURRENT_SOURCE_DIR} cpu-x86.h x86_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-x86.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-x86.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-arm64.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_ARM64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-arm64.h arm64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm64.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_ARM64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-arm64.h arm64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm64.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm64.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-arm.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_ARM ${CMAKE_CURRENT_SOURCE_DIR} cpu-arm.h arm_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_ARM ${CMAKE_CURRENT_SOURCE_DIR} cpu-arm.h arm_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-arm.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-riscv64.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_RISCV64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-riscv64.h riscv64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-riscv64.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_RISCV64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-riscv64.h riscv64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-riscv64.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-riscv64.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-s390x.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_S390X ${CMAKE_CURRENT_SOURCE_DIR} cpu-s390x.h s390x_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-s390x.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_S390X ${CMAKE_CURRENT_SOURCE_DIR} cpu-s390x.h s390x_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-s390x.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-s390x.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-wasm.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_WASM ${CMAKE_CURRENT_SOURCE_DIR} cpu-wasm.h wasm_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-wasm.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_WASM ${CMAKE_CURRENT_SOURCE_DIR} cpu-wasm.h wasm_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-wasm.mdesc DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py mini-ops.h ${CMAKE_CURRENT_SOURCE_DIR}/cpu-wasm.mdesc VERBATIM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cpu-ppc64.h - COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_POWERPC64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-ppc64.h ppc64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-ppc64.mdesc + COMMAND ${Python_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/genmdesc.py TARGET_POWERPC64 ${CMAKE_CURRENT_SOURCE_DIR} cpu-ppc64.h ppc64_cpu_desc ${CMAKE_CURRENT_SOURCE_DIR}/cpu-ppc64.mdesc VERBATIM ) diff --git a/src/runtime/src/mono/msbuild/android/build/AndroidBuild.targets b/src/runtime/src/mono/msbuild/android/build/AndroidBuild.targets index 56dd94a5983..886e99635a3 100644 --- a/src/runtime/src/mono/msbuild/android/build/AndroidBuild.targets +++ b/src/runtime/src/mono/msbuild/android/build/AndroidBuild.targets @@ -251,6 +251,7 @@ ForceAOT="$(RunAOTCompilation)" ForceFullAOT="$(ForceFullAOT)" ForceInterpreter="$(MonoForceInterpreter)" + InvariantGlobalization="$(InvariantGlobalization)" IsLibraryMode="$(_IsLibraryMode)" MainLibraryFileName="$(MainLibraryFileName)" RuntimeHeaders="@(RuntimeHeaders)" diff --git a/src/runtime/src/native/corehost/apphost/static/CMakeLists.txt b/src/runtime/src/native/corehost/apphost/static/CMakeLists.txt index 30118f679da..7d7d975d4bd 100644 --- a/src/runtime/src/native/corehost/apphost/static/CMakeLists.txt +++ b/src/runtime/src/native/corehost/apphost/static/CMakeLists.txt @@ -166,10 +166,11 @@ else() ) if(NOT CLR_CMAKE_TARGET_ANDROID) - list(APPEND NATIVE_LIBS - System.Net.Security.Native-Static - System.Security.Cryptography.Native.OpenSsl-Static - ) + list(APPEND NATIVE_LIBS System.Net.Security.Native-Static) + + if(NOT CLR_CMAKE_TARGET_APPLE) + list(APPEND NATIVE_LIBS System.Security.Cryptography.Native.OpenSsl-Static) + endif() else() list(APPEND NATIVE_LIBS System.Security.Cryptography.Native.Android-Static @@ -204,7 +205,7 @@ else() include(${CLR_SRC_NATIVE_DIR}/libs/System.Native/extra_libs.cmake) append_extra_system_libs(NATIVE_LIBS) - if(NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER) + if(NOT CLR_CMAKE_TARGET_APPLE AND NOT CLR_CMAKE_TARGET_ANDROID AND NOT CLR_CMAKE_TARGET_BROWSER) # Additional requirements for System.Security.Cryptography.Native.OpenSsl include(${CLR_SRC_NATIVE_DIR}/libs/System.Security.Cryptography.Native/extra_libs.cmake) append_extra_cryptography_libs(NATIVE_LIBS) diff --git a/src/runtime/src/native/corehost/build.sh b/src/runtime/src/native/corehost/build.sh index b7df4cc8212..63c3b6d996e 100755 --- a/src/runtime/src/native/corehost/build.sh +++ b/src/runtime/src/native/corehost/build.sh @@ -60,7 +60,10 @@ __IntermediatesDir="$__RootBinDir/obj/$__TargetRid.$__BuildType" export __BinDir __IntermediatesDir __RuntimeFlavor __CMakeArgs="-DCLI_CMAKE_PKG_RID=\"$__TargetRid\" -DCLI_CMAKE_FALLBACK_OS=\"$__HostFallbackOS\" -DCLI_CMAKE_COMMIT_HASH=\"$__commit_hash\" $__CMakeArgs" -__CMakeArgs="-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild $__CMakeArgs" + +if [[ "$__TargetOS" != osx ]]; then + __CMakeArgs="-DFEATURE_DISTRO_AGNOSTIC_SSL=$__PortableBuild $__CMakeArgs" +fi # Specify path to be set for CMAKE_INSTALL_PREFIX. # This is where all built CoreClr libraries will copied to. diff --git a/src/runtime/src/native/corehost/hostpolicy/hostpolicy_context.cpp b/src/runtime/src/native/corehost/hostpolicy/hostpolicy_context.cpp index b562d0e09ae..9c0c7c0468d 100644 --- a/src/runtime/src/native/corehost/hostpolicy/hostpolicy_context.cpp +++ b/src/runtime/src/native/corehost/hostpolicy/hostpolicy_context.cpp @@ -70,11 +70,13 @@ namespace return SystemResolveDllImport(entry_point_name); } +#if !defined(TARGET_OSX) if (strcmp(library_name, LIB_NAME("System.Security.Cryptography.Native.OpenSsl")) == 0) { return CryptoResolveDllImport(entry_point_name); } -#endif +#endif // !defined(TARGET_OSX) +#endif // !defined(_WIN32) if (strcmp(library_name, LIB_NAME("System.IO.Compression.Native")) == 0) { diff --git a/src/runtime/src/native/external/llvm-libunwind/include/__libunwind_config.h b/src/runtime/src/native/external/llvm-libunwind/include/__libunwind_config.h index 35e5a73de03..ec56ded7e28 100644 --- a/src/runtime/src/native/external/llvm-libunwind/include/__libunwind_config.h +++ b/src/runtime/src/native/external/llvm-libunwind/include/__libunwind_config.h @@ -42,7 +42,7 @@ # if defined(__i386__) # define _LIBUNWIND_TARGET_I386 # define _LIBUNWIND_CONTEXT_SIZE 13 -# define _LIBUNWIND_CURSOR_SIZE 19 +# define _LIBUNWIND_CURSOR_SIZE 20 # define _LIBUNWIND_HIGHEST_DWARF_REGISTER _LIBUNWIND_HIGHEST_DWARF_REGISTER_X86 # elif defined(__x86_64__) # define _LIBUNWIND_TARGET_X86_64 1 @@ -178,17 +178,13 @@ #if __loongarch_grlen == 64 #define _LIBUNWIND_CONTEXT_SIZE 98 #define _LIBUNWIND_CURSOR_SIZE 110 -#elif defined(HOST_WASM) -#define _LIBUNWIND_TARGET_WASM 1 -// TODO: Determine the right values -#define _LIBUNWIND_CONTEXT_SIZE 0xbadf00d -#define _LIBUNWIND_CURSOR_SIZE 0xbadf00d #else #error "Unsupported LoongArch ABI" #endif #define _LIBUNWIND_HIGHEST_DWARF_REGISTER \ _LIBUNWIND_HIGHEST_DWARF_REGISTER_LOONGARCH #elif defined(__wasm__) +#define _LIBUNWIND_TARGET_WASM 1 // Unused #define _LIBUNWIND_CONTEXT_SIZE 0 #define _LIBUNWIND_CURSOR_SIZE 0 diff --git a/src/runtime/src/native/libs/CMakeLists.txt b/src/runtime/src/native/libs/CMakeLists.txt index c90e9b8a45d..cf8b2b47fbd 100644 --- a/src/runtime/src/native/libs/CMakeLists.txt +++ b/src/runtime/src/native/libs/CMakeLists.txt @@ -150,18 +150,12 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) if (CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) # skip for now - elseif (CLR_CMAKE_TARGET_MACCATALYST) - add_subdirectory(System.Net.Security.Native) - # 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_IOS) - add_subdirectory(System.Net.Security.Native) - # 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 - # 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_APPLE) + if (NOT CLR_CMAKE_TARGET_TVOS) # no gssapi on tvOS, see https://developer.apple.com/documentation/gss + add_subdirectory(System.Net.Security.Native) + endif () + + add_subdirectory(System.Security.Cryptography.Native.Apple) elseif (CLR_CMAKE_TARGET_ANDROID AND NOT FORCE_ANDROID_OPENSSL) add_subdirectory(System.Security.Cryptography.Native.Android) elseif (FORCE_ANDROID_OPENSSL) @@ -170,8 +164,4 @@ if (CLR_CMAKE_TARGET_UNIX OR CLR_CMAKE_TARGET_BROWSER OR CLR_CMAKE_TARGET_WASI) add_subdirectory(System.Net.Security.Native) add_subdirectory(System.Security.Cryptography.Native) endif () - - if (CLR_CMAKE_TARGET_APPLE) - add_subdirectory(System.Security.Cryptography.Native.Apple) - endif () endif () diff --git a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c index 5163aa5b121..ef27e7bb832 100644 --- a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c +++ b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/entrypoints.c @@ -62,7 +62,6 @@ static const Entry s_cryptoAppleNative[] = DllImportEntry(AppleCryptoNative_SetKeychainNeverLock) DllImportEntry(AppleCryptoNative_SslCopyCADistinguishedNames) DllImportEntry(AppleCryptoNative_SslCopyCertChain) - DllImportEntry(AppleCryptoNative_SslIsHostnameMatch) DllImportEntry(AppleCryptoNative_SslRead) DllImportEntry(AppleCryptoNative_SslSetBreakOnCertRequested) DllImportEntry(AppleCryptoNative_SslSetBreakOnClientAuth) diff --git a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c index 2fba375bd42..2218fdaab5a 100644 --- a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c +++ b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.c @@ -416,181 +416,6 @@ PAL_TlsIo AppleCryptoNative_SslRead(SSLContextRef sslContext, uint8_t* buf, uint return OSStatusToPAL_TlsIo(status); } -int32_t AppleCryptoNative_SslIsHostnameMatch(SSLContextRef sslContext, CFStringRef cfHostname, CFDateRef notBefore, int32_t* pOSStatus) -{ - if (pOSStatus != NULL) - *pOSStatus = noErr; - - if (sslContext == NULL || notBefore == NULL || pOSStatus == NULL) - return -1; - - if (cfHostname == NULL) - return -2; - - SecPolicyRef sslPolicy = SecPolicyCreateSSL(true, cfHostname); - - if (sslPolicy == NULL) - return -3; - - CFMutableArrayRef certs = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - - if (certs == NULL) - return -4; - - SecTrustRef existingTrust = NULL; -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - OSStatus osStatus = SSLCopyPeerTrust(sslContext, &existingTrust); -#pragma clang diagnostic pop - - if (osStatus != noErr) - { - CFRelease(certs); - *pOSStatus = osStatus; - return -5; - } - - CFMutableArrayRef anchors = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks); - - if (anchors == NULL) - { - CFRelease(certs); - CFRelease(existingTrust); - return -6; - } - - CFIndex certificateCount = SecTrustGetCertificateCount(existingTrust); - - for (CFIndex i = 0; i < certificateCount; i++) - { -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - SecCertificateRef item = SecTrustGetCertificateAtIndex(existingTrust, i); -#pragma clang diagnostic pop - - CFArrayAppendValue(certs, item); - - // Copy the EE cert into the anchors set, this will make the chain part - // always return true. - if (i == 0) - { - CFArrayAppendValue(anchors, item); - } - } - - SecTrustRef trust = NULL; - osStatus = SecTrustCreateWithCertificates(certs, sslPolicy, &trust); - int32_t ret = INT_MIN; - - if (osStatus == noErr) - { - osStatus = SecTrustSetAnchorCertificates(trust, anchors); - } - - if (osStatus == noErr) - { - osStatus = SecTrustSetVerifyDate(trust, notBefore); - } - - if (osStatus == noErr) - { - SecTrustResultType trustResult; - memset(&trustResult, 0, sizeof(SecTrustResultType)); - -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wdeprecated-declarations" - osStatus = SecTrustEvaluate(trust, &trustResult); - - if (trustResult == kSecTrustResultRecoverableTrustFailure && osStatus == noErr && certificateCount > 1) - { - // If we get recoverable failure, let's try it again with full anchor list. - // We already stored just the first certificate into anchors; now we store the rest. - for (CFIndex i = 1; i < certificateCount; i++) - { - CFArrayAppendValue(anchors, SecTrustGetCertificateAtIndex(existingTrust, i)); - } - - osStatus = SecTrustSetAnchorCertificates(trust, anchors); - if (osStatus == noErr) - { - memset(&trustResult, 0, sizeof(SecTrustResultType)); - osStatus = SecTrustEvaluate(trust, &trustResult); - } - } -#pragma clang diagnostic pop - - if (osStatus == noErr && trustResult != kSecTrustResultUnspecified && trustResult != kSecTrustResultProceed) - { - // If evaluation succeeded but result is not trusted try to get details. - CFDictionaryRef detailsAndStuff = SecTrustCopyResult(trust); - - if (detailsAndStuff != NULL) - { - CFArrayRef details = CFDictionaryGetValue(detailsAndStuff, CFSTR("TrustResultDetails")); - - if (details != NULL && CFArrayGetCount(details) > 0) - { - CFArrayRef statusCodes = CFDictionaryGetValue(CFArrayGetValueAtIndex(details,0), CFSTR("StatusCodes")); - - if (statusCodes != NULL) - { - OSStatus status = 0; - // look for first failure to keep it simple. Normally, there will be exactly one. - for (int i = 0; i < CFArrayGetCount(statusCodes); i++) - { - CFNumberGetValue(CFArrayGetValueAtIndex(statusCodes, i), kCFNumberSInt32Type, &status); - if (status != noErr) - { - *pOSStatus = status; - break; - } - } - } - } - - CFRelease(detailsAndStuff); - } - } - - if (osStatus != noErr) - { - ret = -7; - *pOSStatus = osStatus; - } - else if (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed) - { - ret = 1; - } - else if (trustResult == kSecTrustResultDeny || trustResult == kSecTrustResultRecoverableTrustFailure) - { - ret = 0; - } - else - { - ret = -8; - } - } - else - { - *pOSStatus = osStatus; - } - - if (trust != NULL) - CFRelease(trust); - - if (certs != NULL) - CFRelease(certs); - - if (anchors != NULL) - CFRelease(anchors); - - if (existingTrust != NULL) - CFRelease(existingTrust); - - CFRelease(sslPolicy); - return ret; -} - int32_t AppleCryptoNative_SslShutdown(SSLContextRef sslContext) { #pragma clang diagnostic push diff --git a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h index 14b8d790970..8a73e052717 100644 --- a/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h +++ b/src/runtime/src/native/libs/System.Security.Cryptography.Native.Apple/pal_ssl.h @@ -226,17 +226,6 @@ written: Receives the number of bytes written into buf PALEXPORT PAL_TlsIo AppleCryptoNative_SslRead(SSLContextRef sslContext, uint8_t* buf, uint32_t bufLen, uint32_t* written); -/* -Check to see if the server identity certificate for this connection matches the requested hostname. - -notBefore: Specify the EE/leaf certificate's notBefore value to prevent a false negative due to -the certificate being expired (or not yet valid). - -Returns 1 on match, 0 on mismatch, any other value indicates an invalid state. -*/ -PALEXPORT int32_t -AppleCryptoNative_SslIsHostnameMatch(SSLContextRef sslContext, CFStringRef cfHostname, CFDateRef notBefore, int32_t* pOSStatus); - /* Generate a TLS Close alert to terminate the session. diff --git a/src/runtime/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt b/src/runtime/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt index ec0ad0fc7db..c875413edd3 100644 --- a/src/runtime/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt +++ b/src/runtime/src/native/libs/System.Security.Cryptography.Native/CMakeLists.txt @@ -68,18 +68,6 @@ if (LOCAL_BUILD) ${CMAKE_CURRENT_BINARY_DIR}/pal_config.h) endif() - -# Always build portable on macOS because OpenSSL is not a system component -# and our prebuilts should not assume a specific ABI version for the types -# that use OpenSSL at runtime. -if (CLR_CMAKE_TARGET_OSX OR CLR_CMAKE_TARGET_MACCATALYST) - set(FEATURE_DISTRO_AGNOSTIC_SSL True) - - # by default uninitialized variables like the shim _ptr functions, will turn into common symbols - # and on OSX those have linking problems in libraries (ELF vs. Mach-O difference) - add_compile_options(-fno-common) -endif() - if (FEATURE_DISTRO_AGNOSTIC_SSL) list(APPEND NATIVECRYPTO_SOURCES opensslshim.c @@ -125,16 +113,14 @@ if (GEN_SHARED_LIB) endif() endif() - if (NOT CLR_CMAKE_TARGET_MACCATALYST AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS AND NOT CLR_CMAKE_TARGET_ANDROID) - add_custom_command(TARGET System.Security.Cryptography.Native.OpenSsl POST_BUILD - COMMENT "Verifying System.Security.Cryptography.Native.OpenSsl entry points against entrypoints.c " - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../verify-entrypoints.sh - $ - ${CMAKE_CURRENT_SOURCE_DIR}/entrypoints.c - ${CMAKE_NM} - VERBATIM - ) - endif() + add_custom_command(TARGET System.Security.Cryptography.Native.OpenSsl POST_BUILD + COMMENT "Verifying System.Security.Cryptography.Native.OpenSsl entry points against entrypoints.c " + COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../verify-entrypoints.sh + $ + ${CMAKE_CURRENT_SOURCE_DIR}/entrypoints.c + ${CMAKE_NM} + VERBATIM + ) target_link_libraries(System.Security.Cryptography.Native.OpenSsl PRIVATE diff --git a/src/runtime/src/native/libs/build-native.sh b/src/runtime/src/native/libs/build-native.sh index 5169732c2d6..5055b05839d 100755 --- a/src/runtime/src/native/libs/build-native.sh +++ b/src/runtime/src/native/libs/build-native.sh @@ -83,6 +83,9 @@ elif [[ "$__TargetOS" == ios || "$__TargetOS" == iossimulator ]]; then elif [[ "$__TargetOS" == tvos || "$__TargetOS" == tvossimulator ]]; then # nothing to do here true +elif [[ "$__TargetOS" == osx || "$__TargetOS" == maccatalyst ]]; then + # nothing to do here + true elif [[ "$__TargetOS" == android && -z "$ROOTFS_DIR" ]]; then # nothing to do here true diff --git a/src/runtime/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs b/src/runtime/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs index 006b746ef0d..bf3d76bcb24 100644 --- a/src/runtime/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs +++ b/src/runtime/src/tasks/AndroidAppBuilder/AndroidAppBuilder.cs @@ -108,6 +108,11 @@ public class AndroidAppBuilderTask : Task public bool ForceInterpreter { get; set; } + /// + /// Indicates whether we want to use invariant globalization mode. + /// + public bool InvariantGlobalization { get; set; } + [Output] public string ApkBundlePath { get; set; } = ""!; @@ -141,6 +146,7 @@ public override bool Execute() apkBuilder.NativeDependencies = NativeDependencies; apkBuilder.ExtraLinkerArguments = ExtraLinkerArguments; apkBuilder.RuntimeFlavor = RuntimeFlavor; + apkBuilder.InvariantGlobalization = InvariantGlobalization; (ApkBundlePath, ApkPackageId) = apkBuilder.BuildApk(RuntimeIdentifier, MainLibraryFileName, RuntimeHeaders); return true; diff --git a/src/runtime/src/tasks/AndroidAppBuilder/ApkBuilder.cs b/src/runtime/src/tasks/AndroidAppBuilder/ApkBuilder.cs index 21fd800c896..df0772393e7 100644 --- a/src/runtime/src/tasks/AndroidAppBuilder/ApkBuilder.cs +++ b/src/runtime/src/tasks/AndroidAppBuilder/ApkBuilder.cs @@ -424,6 +424,11 @@ public ApkBuilder(TaskLoggingHelper logger) envVariables += $"\t\tsetEnv(\"{name}\", \"{value}\");\n"; } + if (InvariantGlobalization) + { + envVariables += $"\t\tsetEnv(\"DOTNET_SYSTEM_GLOBALIZATION_INVARIANT\", \"true\");\n"; + } + string jniLibraryName = (IsLibraryMode) ? ProjectName! : (StaticLinkedRuntime && IsCoreCLR) ? "monodroid" : "System.Security.Cryptography.Native.Android"; string monoRunner = Utils.GetEmbeddedResource("MonoRunner.java") diff --git a/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs b/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs index 00d9e45ae2a..38f6d51b32a 100644 --- a/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs +++ b/src/runtime/src/tests/Common/GenerateHWIntrinsicTests/GenerateHWIntrinsicTests_Arm.cs @@ -4896,6 +4896,20 @@ ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWideningAndAdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(left, right, i) != result[i]", ["GetIterResult"] = "(UInt32) Helpers.AddPairwiseWidening(left, right, i)"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_AddPairwiseWideningAndAdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddPairwiseWideningAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddPairwiseWidening(left, right, i) != result[i]", ["GetIterResult"] = "(UInt64) Helpers.AddPairwiseWidening(left, right, i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingEven(leftOp[Helpers.NarrowIdx(i)], rightOp[Helpers.NarrowIdx(i)], i)"}), + + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_AddRoundedHighNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.AddRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(SByte) Helpers.AddSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int16) Helpers.AddSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_AddSaturate_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "AddSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.AddSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "(Int32) Helpers.AddSaturate(left[i], right[i])"}), @@ -4999,6 +5013,15 @@ ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedSubtractHalving_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedSubtractHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.FusedSubtractHalving(left[i], right[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_FusedAddRoundedHalving_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "FusedAddRoundedHalving", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.FusedAddRoundedHalving(left[i], right[i])", ["GetIterResult"] = "Helpers.FusedAddRoundedHalving(leftOp[i], rightOp[i])",}), + ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorEvenOdd_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorEvenOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorEvenOdd(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorEvenOdd(first, second, third)[i]"}), @@ -5016,6 +5039,108 @@ ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), ("SveVecTernOpTest.template", new Dictionary { ["TestName"] = "Sve2_InterleavingXorOddEven_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "InterleavingXorOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.InterleavingXorOddEven(firstOp, secondOp, thirdOp)[i]", ["GetIterResult"] = "Helpers.InterleavingXorOddEven(first, second, third)[i]"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["Imm"] = "2", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyAddBySelectedScalar_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyAddBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["Imm"] = "0", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAdd(firstOp[i], secondOp[i], thirdOp[Imm])",}), + + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndAdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])",}), + + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndAdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "1", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndAdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndAdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "7", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndAdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "3", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])",}), + + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndAdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])",}), + + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndAdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndAdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndAdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])",}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndAdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndAdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyAddWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])",}), + + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalar_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.Multiply(firstOp[i], secondOp[Imm])", ["GetIterResult"] = "Helpers.Multiply(firstOp[i], secondOp[Imm])"}), + + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt16()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt64()",["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["Imm"] = "7", ["InvalidImm"] = "8", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["Imm"] = "3", ["InvalidImm"] = "4", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplySubtractBySelectedScalar_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplySubtractBySelectedScalar", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64",["Op4BaseType"] = "Byte",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["Imm"] = "1", ["InvalidImm"] = "2", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtract(firstOp[i], secondOp[i], thirdOp[Imm])"}), + + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningEvenAndSubtract_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[2 * i])"}), + + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEvenAndSubtract_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEvenAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i], thirdOp[Imm])"}), + + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueOp3"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + ("SveVecTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyWideningOddAndSubtract_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[2 * i + 1])"}), + + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndSubtract_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndSubtract_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndSubtract_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])"}), + ("SveVecImmTernOpTest.template",new Dictionary {["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOddAndSubtract_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOddAndSubtract", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32",["Op4BaseType"] = "UInt64",["LargestVectorSize"] = "64",["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()",["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()",["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])", ["GetIterResult"] = "Helpers.MultiplySubtractWidening(firstOp[i], secondOp[2 * i + 1], thirdOp[Imm])"}), + + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEven_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i], secondOp[Imm])"}), + + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary { ["TestName"] = "Sve2_MultiplyWideningOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.MultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOdd_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueMask"] = "Helpers.getMaskInt32()", ["Imm"] = "3", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOdd_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueMask"] = "Helpers.getMaskInt64()", ["Imm"] = "1", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOdd_uint_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "6", ["InvalidImm"] = "8", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])"}), + ("SveVecImmBinOpTest.template",new Dictionary { ["TestName"] = "Sve2_MultiplyBySelectedScalarWideningOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "MultiplyBySelectedScalarWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "2", ["InvalidImm"] = "4", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])", ["GetIterResult"] = "Helpers.MultiplyWidening(firstOp[2 * i + 1], secondOp[Imm])"}), + + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_PolynomialMultiply_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiply(left[i], right[i])", ["GetIterResult"] = "Helpers.PolynomialMultiply(leftOp[i], rightOp[i])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_PolynomialMultiply_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiply", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["NextValueMask"] = "Helpers.getMaskSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiply(left[i], right[i])", ["GetIterResult"] = "Helpers.PolynomialMultiply(leftOp[i], rightOp[i])"}), + + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_PolynomialMultiplyWideningEven_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.PolynomialMultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_PolynomialMultiplyWideningEven_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiplyWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiplyWidening(left[2 * i], right[2 * i])", ["GetIterResult"] = "Helpers.PolynomialMultiplyWidening(leftOp[2 * i], rightOp[2 * i])"}), + + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_PolynomialMultiplyWideningOdd_ushort_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["NextValueMask"] = "Helpers.getMaskUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.PolynomialMultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_PolynomialMultiplyWideningOdd_ulong_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "PolynomialMultiplyWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != Helpers.PolynomialMultiplyWidening(left[2 * i + 1], right[2 * i + 1])", ["GetIterResult"] = "Helpers.PolynomialMultiplyWidening(leftOp[2 * i + 1], rightOp[2 * i + 1])"}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRounded_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (sbyte)Helpers.SveShiftArithmeticRounded(left[i], right[i])", ["GetIterResult"] = "(sbyte)Helpers.SveShiftArithmeticRounded(leftOp[i], rightOp[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRounded_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (short)Helpers.SveShiftArithmeticRounded(left[i], right[i])", ["GetIterResult"] = "(short)Helpers.SveShiftArithmeticRounded(leftOp[i], rightOp[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_ShiftArithmeticRounded_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftArithmeticRounded", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "result[i] != (int) Helpers.SveShiftArithmeticRounded(left[i], right[i])", ["GetIterResult"] = "(int) Helpers.SveShiftArithmeticRounded(leftOp[i], rightOp[i])"}), @@ -5183,6 +5308,11 @@ ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueMask"] = "Helpers.getMaskUInt32()", ["Imm"] = "13", ["InvalidImm"] = "17", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), ("SveVecImmBinOpTest.template",new Dictionary {["TestName"] = "Sve2_ShiftRightLogicalRoundedNarrowingSaturateOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "ShiftRightLogicalRoundedNarrowingSaturateOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueMask"] = "Helpers.getMaskUInt64()", ["Imm"] = "28", ["InvalidImm"] = "33", ["ValidateIterResult"] = "result[i] != Helpers.ShiftRightLogicalRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)", ["GetIterResult"] = "Helpers.ShiftRightLogicalRoundedNarrowingSaturateOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], Imm, i)",}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractBorrowWideningEven_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractBorrowWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractBorrowWideningEven(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractBorrowWideningEven(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractBorrowWideningEven_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractBorrowWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractBorrowWideningEven(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractBorrowWideningEven(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractBorrowWideningOdd_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractBorrowWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractBorrowWideningOdd(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractBorrowWideningOdd(first, second, third)"}), + ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractBorrowWideningOdd_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractBorrowWideningOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractBorrowWideningOdd(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractBorrowWideningOdd(first, second, third)"}), + ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i)"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i)"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingEven(left, right, i)"}), @@ -5197,6 +5327,20 @@ ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i)"}), ("SveVecTernOpFirstArgTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractHighNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i) != result[i]", ["GetIterResult"] = "Helpers.SubtractHighNarrowingOdd(first, second, third, i)"}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpDifferentRetType.template",new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingEven_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingEven(left[Helpers.NarrowIdx(i)], right[Helpers.NarrowIdx(i)], i)",}), + + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_sbyte_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_short_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_int_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_byte_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_ushort_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecTernOpTest.template", new Dictionary {["TestName"] = "Sve2_SubtractRoundedHighNarrowingOdd_uint_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractRoundedHighNarrowingOdd", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i) != result[i]", ["GetIterResult"] = "Helpers.SubtractRoundedHighNarrowingOdd(firstOp[i], secondOp[Helpers.NarrowIdx(i)], thirdOp[Helpers.NarrowIdx(i)], i)",}), + ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), @@ -5206,15 +5350,6 @@ ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturate_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturate", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(left[i], right[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(left[i], right[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "SByte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "SByte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetSByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_long", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractSaturateReversed_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractSaturateReversed", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractSaturate(right[i], left[i]) != result[i]", ["GetIterResult"] = "Helpers.SubtractSaturate(right[i], left[i])"}), - ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_short_short_sbyte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "SByte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetSByte()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2])"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_int_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2])"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningEven_long_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i], right[i * 2])"}), @@ -5251,11 +5386,6 @@ ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOddEven_int_short", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt16()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2])"}), ("SveVecBinOpDifferentRetType.template", new Dictionary { ["TestName"] = "Sve2_SubtractWideningOddEven_long_int", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWideningOddEven", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Int64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Int32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Int32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetInt32()", ["ConvertFunc"] = "", ["ValidateIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2]) != result[i]", ["GetIterResult"] = "Helpers.SubtractWidening(left[i * 2 + 1], right[i * 2])"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractWithBorrowWideningLower_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWithBorrowWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractWithBorrowWideningLower(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractWithBorrowWideningLower(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractWithBorrowWideningLower_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWithBorrowWideningLower", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractWithBorrowWideningLower(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractWithBorrowWideningLower(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractWithBorrowWideningUpper_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWithBorrowWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt32()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractWithBorrowWideningUpper(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractWithBorrowWideningUpper(first, second, third)"}), - ("SveVecTernOpVecTest.template", new Dictionary { ["TestName"] = "Sve2_SubtractWithBorrowWideningUpper_ulong", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "SubtractWithBorrowWideningUpper", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt64", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt64", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt64", ["Op3VectorType"] = "Vector", ["Op3BaseType"] = "UInt64", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt64()", ["NextValueOp3"] = "TestLibrary.Generator.GetUInt64()", ["ValidateVectorResult"] = "!result.SequenceEqual(Helpers.SubtractWithBorrowWideningUpper(firstOp, secondOp, thirdOp))", ["GetVectorResult"] = "Helpers.SubtractWithBorrowWideningUpper(first, second, third)"}), - ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_byte", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "Byte", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "Byte", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "Byte", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetByte()", ["NextValueOp2"] = "TestLibrary.Generator.GetByte()", ["ValidateEntry"] = "(third[i] < (Byte) RetElementCount * 2) ? ((third[i] < (Byte) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(Byte) RetElementCount])) : (result[i] != 0)"}), ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_ushort", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt16", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt16", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt16", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt16()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt16()", ["ValidateEntry"] = "(third[i] < (UInt16) RetElementCount * 2) ? ((third[i] < (UInt16) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(UInt16) RetElementCount])) : (result[i] != 0)"}), ("SveVecBinOpTupleTest.template", new Dictionary { ["TestName"] = "Sve2_VectorTableLookup_uint", ["Isa"] = "Sve2", ["LoadIsa"] = "Sve2", ["Method"] = "VectorTableLookup", ["RetVectorType"] = "Vector", ["RetBaseType"] = "UInt32", ["Op1VectorType"] = "Vector", ["Op1BaseType"] = "UInt32", ["Op2VectorType"] = "Vector", ["Op2BaseType"] = "UInt32", ["LargestVectorSize"] = "64", ["NextValueOp1"] = "TestLibrary.Generator.GetUInt32()", ["NextValueOp2"] = "TestLibrary.Generator.GetUInt32()", ["ValidateEntry"] = "(third[i] < (UInt32) RetElementCount * 2) ? ((third[i] < (UInt32) RetElementCount) ? (result[i] != first[third[i]]) : (result[i] != second[third[i]-(UInt32) RetElementCount])) : (result[i] != 0)"}), diff --git a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs index e1ddb8238d1..d8643e94617 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/Helpers.cs @@ -2142,9 +2142,9 @@ public static float CompareTest(float left, float right) public static short AbsoluteDifferenceWideningLowerAndAddOdd(short[] op1, sbyte[] op2, sbyte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static short AbsoluteDifferenceWideningEven(sbyte[] op1, sbyte[] op2, int i) => (short) AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static short AbsoluteDifferenceWideningEven(sbyte[] op1, sbyte[] op2, int i) => (short)AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static short AbsoluteDifferenceWideningOdd(sbyte[] op1, sbyte[] op2, int i) => (short) AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static short AbsoluteDifferenceWideningOdd(sbyte[] op1, sbyte[] op2, int i) => (short)AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); public static short AddAcrossWidening(sbyte[] op1) => Reduce(AddWidening, op1); @@ -2302,9 +2302,9 @@ private static long Reduce(Func reduceOp, sbyte[] op1) public static int AbsoluteDifferenceWideningLowerAndAddOdd(int[] op1, short[] op2, short[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static int AbsoluteDifferenceWideningEven(short[] op1, short[] op2, int i) => (int) AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static int AbsoluteDifferenceWideningEven(short[] op1, short[] op2, int i) => (int)AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static int AbsoluteDifferenceWideningOdd(short[] op1, short[] op2, int i) => (int) AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static int AbsoluteDifferenceWideningOdd(short[] op1, short[] op2, int i) => (int)AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); public static int AddAcrossWidening(short[] op1) => Reduce(AddWidening, op1); @@ -2519,9 +2519,9 @@ private static long Reduce(Func reduceOp, short[] op1) public static long AbsoluteDifferenceWideningLowerAndAddOdd(long[] op1, int[] op2, int[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static long AbsoluteDifferenceWideningEven(int[] op1, int[] op2, int i) => (long) AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static long AbsoluteDifferenceWideningEven(int[] op1, int[] op2, int i) => (long)AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static long AbsoluteDifferenceWideningOdd(int[] op1, int[] op2, int i) => (long) AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static long AbsoluteDifferenceWideningOdd(int[] op1, int[] op2, int i) => (long)AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); public static long AddAcrossWidening(int[] op1) => Reduce(AddWidening, op1); @@ -2774,7 +2774,7 @@ private static long Reduce(Func reduceOp, int[] op1) public static ushort AbsoluteDifferenceWideningLowerAndAddOdd(ushort[] op1, byte[] op2, byte[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static ushort AbsoluteDifferenceWideningEven(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static ushort AbsoluteDifferenceWideningEven(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); public static ushort AbsoluteDifferenceWideningOdd(byte[] op1, byte[] op2, int i) => AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); @@ -2918,9 +2918,9 @@ private static ulong Reduce(Func reduceOp, byte[] op1) public static uint AbsoluteDifferenceWideningLowerAndAddOdd(uint[] op1, ushort[] op2, ushort[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static uint AbsoluteDifferenceWideningEven(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static uint AbsoluteDifferenceWideningEven(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static uint AbsoluteDifferenceWideningOdd(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static uint AbsoluteDifferenceWideningOdd(ushort[] op1, ushort[] op2, int i) => AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); public static uint AddAcrossWidening(ushort[] op1) => Reduce(AddWidening, op1); @@ -3062,9 +3062,9 @@ private static ulong Reduce(Func reduceOp, ushort[] op1) public static ulong AbsoluteDifferenceWideningLowerAndAddOdd(ulong[] op1, uint[] op2, uint[] op3, int i) => AbsoluteDifferenceWideningAndAdd(op1[i], op2[(i * 2) + 1], op3[(i * 2) + 1]); - public static ulong AbsoluteDifferenceWideningEven(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[i*2], op2[i*2]); + public static ulong AbsoluteDifferenceWideningEven(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[i * 2], op2[i * 2]); - public static ulong AbsoluteDifferenceWideningOdd(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[(i*2) + 1], op2[(i*2) + 1]); + public static ulong AbsoluteDifferenceWideningOdd(uint[] op1, uint[] op2, int i) => AbsoluteDifferenceWidening(op1[(i * 2) + 1], op2[(i * 2) + 1]); public static ulong AddAcrossWidening(uint[] op1) => Reduce(AddWidening, op1); @@ -7180,6 +7180,22 @@ private static short PolynomialMult(sbyte op1, sbyte op2) return result; } + private static ulong PolynomialMult(uint op1, uint op2) + { + ulong result = default(ulong); + ulong extendedOp2 = (ulong)op2; + + for (int i = 0; i < 8 * sizeof(uint); i++) + { + if ((op1 & ((uint)1 << i)) != 0) + { + result = (ulong)(result ^ (extendedOp2 << i)); + } + } + + return result; + } + private static poly128_t PolynomialMult(ulong op1, ulong op2) { poly128_t result = default(poly128_t); @@ -7264,6 +7280,8 @@ public static ulong MultiplyHigh(ulong op1, ulong op2) public static long PolynomialMultiplyWideningHi64(long op1, long op2) => (long)PolynomialMult(op1, op2).hi; + public static ulong PolynomialMultiplyWidening(uint op1, uint op2) => PolynomialMult(op1, op2); + public static sbyte Concat(sbyte[] op1, sbyte[] op2, int i) => (i < op1.Length) ? op1[i] : op2[i - op1.Length]; public static sbyte ConcatScalar(sbyte[] op1, sbyte[] op2, int i) @@ -10946,16 +10964,50 @@ public static T[] InterleavingXorOddEven(T[] even, T[] left, T[] right) where { for (int i = 0; i < even.Length; i += 2) { - even[i+1] = left[i+1] ^ right[i]; + even[i + 1] = left[i + 1] ^ right[i]; } return even; } + public static T[] SubtractBorrowWideningEven(T[] op1, T[] op2, T[] op3) + where T : unmanaged, IBinaryInteger + { + T[] result = new T[op1.Length]; + for (int i = 0; i < op1.Length; i += 2) + { + T a = op1[i]; + T b = ~op2[i]; + T carryIn = op3[i + 1] & T.One; + (T sum, T carryOut) = AddWithCarry(a, b, carryIn); + result[i] = sum; + result[i + 1] = carryOut; + } + + return result; + } + + public static T[] SubtractBorrowWideningOdd(T[] op1, T[] op2, T[] op3) + where T : unmanaged, IBinaryInteger + { + T[] result = new T[op1.Length]; + for (int i = 0; i < op1.Length; i += 2) + { + T a = op1[i]; + T b = ~op2[i+1]; + T carryIn = op3[i + 1] & T.One; + (T sum, T carryOut) = AddWithCarry(a, b, carryIn); + result[i] = sum; + result[i + 1] = carryOut; + } + + return result; + } + public static sbyte SubtractHighNarrowingEven(short[] left, short[] right, int i) { if (i % 2 == 0) { - return (sbyte) ((left[i / 2] - right[i / 2]) >> 8); + return (sbyte)((left[i / 2] - right[i / 2]) >> 8); } return 0; @@ -11081,40 +11133,6 @@ public static (T sum, T carryOut) AddWithCarry(T a, T b, T carryIn) return (sum, carryOut); } - public static T[] SubtractWithBorrowWideningLower(T[] op1, T[] op2, T[] op3) - where T : unmanaged, IBinaryInteger - { - T[] result = new T[op1.Length]; - for (int i = 0; i < op1.Length; i += 2) - { - T a = op1[i]; - T b = ~op2[i]; - T carryIn = op3[i + 1] & T.One; - (T sum, T carryOut) = AddWithCarry(a, b, carryIn); - result[i] = sum; - result[i + 1] = carryOut; - } - - return result; - } - - public static T[] SubtractWithBorrowWideningUpper(T[] op1, T[] op2, T[] op3) - where T : unmanaged, IBinaryInteger - { - T[] result = new T[op1.Length]; - for (int i = 0; i < op1.Length; i += 2) - { - T a = op1[i]; - T b = ~op2[i+1]; - T carryIn = op3[i + 1] & T.One; - (T sum, T carryOut) = AddWithCarry(a, b, carryIn); - result[i] = sum; - result[i + 1] = carryOut; - } - - return result; - } - public static T Xor(params T[] ops) where T : IBitwiseOperators { T result = ops[0]; @@ -11388,5 +11406,107 @@ public static U ShiftRightLogicalRoundedNarrowingSaturateOdd(U even, T val { return Odd(even, LogicalShift(val, shift, rounding: true, saturate: true), i); } + + public static W MultiplyAddWidening(W op1, N op2, N op3) + where W : IBinaryInteger + where N : IBinaryInteger + { + dynamic a = op2; + dynamic b = op3; + W product = (W)((W)a * (W)b); + W r = (W)(op1 + product); + return r; + } + + public static W MultiplySubtractWidening(W op1, N op2, N op3) + where W : IBinaryInteger + where N : IBinaryInteger + { + dynamic a = op2; + dynamic b = op3; + W product = (W)((W)a * (W)b); + W r = (W)(op1 - product); + return r; + } + + public static N AddRoundedHighNarrowing(W op1, W op2) + where W : IBinaryInteger + where N : IBinaryInteger + { + int halfsize = default(N).GetByteCount() * 8; + dynamic a = op1; + dynamic b = op2; + ulong sum = (ulong)a + (ulong)b; + ulong bias = 1UL << (halfsize - 1); + dynamic result = sum + bias; + return (N)(result >> halfsize); + } + + public static N AddRoundedHighNarrowingEven(W op1, W op2, int i) + where W : IBinaryInteger + where N : IBinaryInteger, new() + { + return Even(AddRoundedHighNarrowing(op1, op2), i); + } + + public static N AddRoundedHighNarrowingOdd(N even, W op1, W op2, int i) + where W : IBinaryInteger + where N : IBinaryInteger + { + return Odd(even, AddRoundedHighNarrowing(op1, op2), i); + } + + public static N SubtractRoundedHighNarrowing(W op1, W op2) + where W : IBinaryInteger + where N : IBinaryInteger + { + int halfsize = default(N).GetByteCount() * 8; + dynamic a = op1; + dynamic b = op2; + ulong sum = (ulong)a - (ulong)b; + ulong bias = 1UL << (halfsize - 1); + dynamic result = sum + bias; + return (N)(result >> halfsize); + } + + public static N SubtractRoundedHighNarrowingEven(W op1, W op2, int i) + where W : IBinaryInteger + where N : IBinaryInteger, new() + { + return Even(SubtractRoundedHighNarrowing(op1, op2), i); + } + + public static N SubtractRoundedHighNarrowingOdd(N even, W op1, W op2, int i) + where W : IBinaryInteger + where N : IBinaryInteger + { + return Odd(even, SubtractRoundedHighNarrowing(op1, op2), i); + } + + public static long FusedAddRoundedHalving(long op1, long op2) => (long)((ulong)(op1 + op2 + 1) >> 1); + + public static ulong FusedAddRoundedHalving(ulong op1, ulong op2) + { + bool overflow = false; + ulong sum = 0; + try + { + sum = checked(op1 + op2 + 1); + } + catch (OverflowException) + { + overflow = true; + sum = op1 + op2 + 1; + } + + sum >>>= 1; + + if (overflow) + { + sum |= (ulong)(1UL << 63); + } + + return sum; + } } } diff --git a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template index 2d2df308eb2..ad9531b94c7 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveBinaryOpDifferentRetTypeTestTemplate.template @@ -538,7 +538,7 @@ namespace JIT.HardwareIntrinsics.Arm if (!succeeded) { TestLibrary.TestFramework.LogInformation(string.Empty); - TestLibrary.TestFramework.LogInformation($"{nameof(Sve2)}.{nameof({Isa}.{Method})}(Vector, Vector): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof(Sve2)}.{nameof({Isa}.{Method})}<{RetBaseType}>(Vector<{Op1BaseType}>, Vector<{Op2BaseType}>): {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/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template index 4708815e3ba..45907adb29e 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmBinaryOpTestTemplate.template @@ -185,8 +185,8 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueMask} % 2); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueMask} % 2); } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); 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}; } diff --git a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template index 9ce3a334f7d..4117cecd4dd 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveImmTernOpTestTemplate.template @@ -99,11 +99,11 @@ namespace JIT.HardwareIntrinsics.Arm private ulong alignment; - public DataTable({Op1BaseType}[] inArray1, {Op1BaseType}[] inArray2, {Op1BaseType}[] inArray3, {RetBaseType}[] outArray, int alignment) + public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {Op3BaseType}[] inArray3, {RetBaseType}[] outArray, int alignment) { int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op1BaseType}>(); - int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op1BaseType}>(); + int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>(); + int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op3BaseType}>(); int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>(); if ((alignment != 64 && alignment != 16 && alignment != 8) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray) { @@ -123,8 +123,8 @@ namespace JIT.HardwareIntrinsics.Arm 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<{Op1BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); - Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray3Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2); + Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef(inArray3Ptr), ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3); } public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment); @@ -149,8 +149,8 @@ namespace JIT.HardwareIntrinsics.Arm private struct TestStruct { public {Op1VectorType}<{Op1BaseType}> _fld1; - public {Op1VectorType}<{Op1BaseType}> _fld2; - public {Op1VectorType}<{Op1BaseType}> _fld3; + public {Op1VectorType}<{Op2BaseType}> _fld2; + public {Op1VectorType}<{Op3BaseType}> _fld3; public static TestStruct Create() { @@ -158,10 +158,10 @@ namespace JIT.HardwareIntrinsics.Arm 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 < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp3}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op1BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op3BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>()); return testStruct; } @@ -178,19 +178,23 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int LargestVectorSize = {LargestVectorSize}; private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType}); + private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType}); + private static readonly int Op3ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>() / sizeof({Op3BaseType}); private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); private static readonly byte Imm = {Imm}; - private static {Op1BaseType}[] _maskData = new {Op1BaseType}[Op1ElementCount]; + private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; - private static {Op1BaseType}[] _data2 = new {Op1BaseType}[Op1ElementCount]; - private static {Op1BaseType}[] _data3 = new {Op1BaseType}[Op1ElementCount]; + private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; + private static {Op3BaseType}[] _data3 = new {Op3BaseType}[Op3ElementCount]; - private {Op1VectorType}<{Op1BaseType}> _mask; + private {Op1VectorType}<{RetBaseType}> _mask; private {Op1VectorType}<{Op1BaseType}> _fld1; - private {Op1VectorType}<{Op1BaseType}> _fld2; - private {Op1VectorType}<{Op1BaseType}> _fld3; - private {Op1VectorType}<{Op1BaseType}> _falseFld; + private {Op1VectorType}<{Op2BaseType}> _fld2; + private {Op1VectorType}<{Op3BaseType}> _fld3; + private {Op1VectorType}<{RetBaseType}> _falseFld; + private {Op1VectorType}<{RetBaseType}> _falseFld2; + private {Op1VectorType}<{RetBaseType}> _falseFld3; private DataTable _dataTable; @@ -198,19 +202,22 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueMask} % 2); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueMask} % 2); } for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); 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 < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op1BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp3}; } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op1BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op3BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } - for (var i = 0; i < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } - for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp3}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } _dataTable = new DataTable(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], LargestVectorSize); } @@ -224,8 +231,8 @@ namespace JIT.HardwareIntrinsics.Arm var result = {Isa}.{Method}( Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray3Ptr), + Unsafe.Read<{Op1VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op1VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), {Imm} ); @@ -242,8 +249,8 @@ namespace JIT.HardwareIntrinsics.Arm { var result = {Isa}.{Method}( Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray3Ptr), + Unsafe.Read<{Op1VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op1VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), {InvalidImm} ); Console.WriteLine(result); @@ -263,12 +270,14 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load)); - {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{RetBaseType}(SveMaskPattern.All); + {Op1VectorType}<{Op1BaseType}> loadMask = Sve.CreateTrueMask{Op1BaseType}(SveMaskPattern.All); + {Op1VectorType}<{Op2BaseType}> loadMask2 = Sve.CreateTrueMask{Op2BaseType}(SveMaskPattern.All); + {Op1VectorType}<{Op3BaseType}> loadMask3 = Sve.CreateTrueMask{Op3BaseType}(SveMaskPattern.All); var result = {Isa}.{Method}( {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray1Ptr)), - {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray2Ptr)), - {LoadIsa}.Load{Op1VectorType}(loadMask, ({Op1BaseType}*)(_dataTable.inArray3Ptr)), + {LoadIsa}.Load{Op1VectorType}(loadMask2, ({Op2BaseType}*)(_dataTable.inArray2Ptr)), + {LoadIsa}.Load{Op1VectorType}(loadMask3, ({Op3BaseType}*)(_dataTable.inArray3Ptr)), {Imm} ); @@ -280,11 +289,11 @@ namespace JIT.HardwareIntrinsics.Arm { TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead)); - var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op1VectorType}<{Op1BaseType}>), typeof(byte) }) + var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op1VectorType}<{Op2BaseType}>), typeof({Op1VectorType}<{Op3BaseType}>), typeof(byte) }) .Invoke(null, new object[] { Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr), - Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray3Ptr), + Unsafe.Read<{Op1VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr), + Unsafe.Read<{Op1VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr), (byte){Imm} }); @@ -297,8 +306,8 @@ namespace JIT.HardwareIntrinsics.Arm TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead)); var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); - var op2 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray2Ptr); - var op3 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray3Ptr); + var op2 = Unsafe.Read<{Op1VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr); + var op3 = Unsafe.Read<{Op1VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr); var result = {Isa}.{Method}(op1, op2, op3, {Imm}); Unsafe.Write(_dataTable.outArrayPtr, result); @@ -337,64 +346,64 @@ namespace JIT.HardwareIntrinsics.Arm public void ConditionalSelect_Op1() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); } public void ConditionalSelect_Op2() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _falseFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld2); } public void ConditionalSelect_Op3() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _falseFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld3); } public void ConditionalSelect_FalseOp() @@ -403,44 +412,44 @@ namespace JIT.HardwareIntrinsics.Arm ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in FalseValue"); ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); } public void ConditionalSelect_ZeroOp() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> op3, {Op1VectorType}<{Op1BaseType}> falseOp) + private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{RetBaseType}> falseOp) { var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3, Imm), falseOp); Unsafe.Write(_dataTable.outArrayPtr, result); @@ -448,7 +457,7 @@ namespace JIT.HardwareIntrinsics.Arm } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> op3, {Op1VectorType}<{Op1BaseType}> trueOp) + private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{RetBaseType}> trueOp) { var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1, op2, op3, Imm)); Unsafe.Write(_dataTable.outArrayPtr, result); @@ -476,25 +485,25 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op1BaseType}> secondOp, {Op1VectorType}<{Op1BaseType}> thirdOp, {Op1VectorType}<{Op1BaseType}> falseOp, void* output, [CallerMemberName] string method = "") + private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{RetBaseType}> falseOp, void* output, [CallerMemberName] string method = "") { - {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; {Op1BaseType}[] first = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] second = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] third = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] falseVal = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] second = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] third = new {Op3BaseType}[Op3ElementCount]; + {RetBaseType}[] falseVal = new {RetBaseType}[RetElementCount]; {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref first[0]), firstOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref second[0]), secondOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref third[0]), thirdOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref falseVal[0]), falseOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref second[0]), secondOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref third[0]), thirdOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref falseVal[0]), falseOp); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); bool succeeded = true; {TemplateValidationLogicForCndSel} if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op2BaseType}>, {Op1VectorType}<{Op3BaseType}>): {method} failed:"); TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); TestLibrary.TestFramework.LogInformation($" first: ({string.Join(", ", first)})"); TestLibrary.TestFramework.LogInformation($" second: ({string.Join(", ", second)})"); @@ -506,19 +515,19 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op1BaseType}> secondOp, {Op1VectorType}<{Op1BaseType}> thirdOp, {Op1VectorType}<{Op1BaseType}> trueOp, void* output, [CallerMemberName] string method = "") + private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{RetBaseType}> trueOp, void* output, [CallerMemberName] string method = "") { - {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] mask = new {Op1BaseType}[RetElementCount]; {Op1BaseType}[] first = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] second = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] third = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] trueVal = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] second = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] third = new {Op3BaseType}[Op3ElementCount]; + {RetBaseType}[] trueVal = new {RetBaseType}[RetElementCount]; {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref first[0]), firstOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref second[0]), secondOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref third[0]), thirdOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref trueVal[0]), trueOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref second[0]), secondOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref third[0]), thirdOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref trueVal[0]), trueOp); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); bool succeeded = true; @@ -526,7 +535,7 @@ namespace JIT.HardwareIntrinsics.Arm if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op2BaseType}>, {Op1VectorType}<{Op3BaseType}>): {method} failed:"); TestLibrary.TestFramework.LogInformation($" mask: ({string.Join(", ", mask)})"); TestLibrary.TestFramework.LogInformation($" first: ({string.Join(", ", first)})"); TestLibrary.TestFramework.LogInformation($" second: ({string.Join(", ", second)})"); @@ -538,16 +547,16 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op1BaseType}> op2, {Op1VectorType}<{Op1BaseType}> op3, void* result, [CallerMemberName] string method = "") + private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] inArray2 = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] inArray3 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), op2); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), op3); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), op3); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); ValidateResult(inArray1, inArray2, inArray3, outArray, method); @@ -556,19 +565,19 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] inArray2 = new {Op1BaseType}[Op1ElementCount]; - {Op1BaseType}[] inArray3 = new {Op1BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef(op2), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef(op3), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); ValidateResult(inArray1, inArray2, inArray3, outArray, method); } - private void ValidateResult({Op1BaseType}[] firstOp, {Op1BaseType}[] secondOp, {Op1BaseType}[] thirdOp, {RetBaseType}[] result, [CallerMemberName] string method = "") + private void ValidateResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] result, [CallerMemberName] string method = "") { bool succeeded = true; @@ -576,7 +585,7 @@ namespace JIT.HardwareIntrinsics.Arm if (!succeeded) { - TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op1BaseType}>): {method} failed:"); + TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op1VectorType}<{Op2BaseType}>, {Op1VectorType}<{Op3BaseType}>): {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/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template index 13343926763..bdce7267163 100644 --- a/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template +++ b/src/runtime/src/tests/JIT/HardwareIntrinsics/Arm/Shared/_SveTernOpTestTemplate.template @@ -43,15 +43,9 @@ namespace JIT.HardwareIntrinsics.Arm // Validates passing a local works, using Unsafe.Read test.RunLclVarScenario_UnsafeRead(); - // Validates using the same local multiple times works, using Unsafe.Read - test.RunSameLclVarScenario_UnsafeRead(); - // Validates passing an instance member of a class works test.RunClassFldScenario(); - // Validates using the same instance member of a class multiple times works - test.RunSameClassFldScenario(); - // Validates passing the field of a local struct works test.RunStructLclFldScenario(); @@ -161,9 +155,9 @@ namespace JIT.HardwareIntrinsics.Arm 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 < Op1ElementCount; i++) { _data2[i] = {NextValueOp2}; } + for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); - for (var i = 0; i < Op1ElementCount; i++) { _data3[i] = {NextValueOp3}; } + for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op3BaseType}>, byte>(ref testStruct._fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>()); return testStruct; @@ -185,16 +179,20 @@ namespace JIT.HardwareIntrinsics.Arm private static readonly int Op3ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>() / sizeof({Op3BaseType}); private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType}); - private static {Op1BaseType}[] _maskData = new {Op1BaseType}[Op1ElementCount]; + private static {RetBaseType}[] _maskData = new {RetBaseType}[RetElementCount]; private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount]; private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount]; private static {Op3BaseType}[] _data3 = new {Op3BaseType}[Op3ElementCount]; - private {Op1VectorType}<{Op1BaseType}> _mask; + private {Op1VectorType}<{RetBaseType}> _mask; private {Op1VectorType}<{Op1BaseType}> _fld1; private {Op1VectorType}<{Op2BaseType}> _fld2; private {Op1VectorType}<{Op3BaseType}> _fld3; - private {Op1VectorType}<{Op1BaseType}> _falseFld; + private {Op1VectorType}<{RetBaseType}> _falseFld; + + private {Op1VectorType}<{RetBaseType}> _resultFld1; + private {Op1VectorType}<{RetBaseType}> _resultFld2; + private {Op1VectorType}<{RetBaseType}> _resultFld3; private DataTable _dataTable; @@ -202,16 +200,21 @@ namespace JIT.HardwareIntrinsics.Arm { Succeeded = true; - for (var i = 0; i < Op1ElementCount; i++) { _maskData[i] = ({Op1BaseType})({NextValueOp1} % 2); } - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _mask), ref Unsafe.As<{Op1BaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + for (var i = 0; i < RetElementCount; i++) { _maskData[i] = ({RetBaseType})({NextValueOp1} % 2); } 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<{Op1VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; } + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _mask), ref Unsafe.As<{RetBaseType}, byte>(ref _maskData[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op2BaseType}>>()); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op3BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op3BaseType}>>()); - Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _falseFld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _resultFld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _resultFld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); + Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{RetBaseType}>, byte>(ref _resultFld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{RetBaseType}>>()); for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; } for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; } @@ -283,20 +286,6 @@ namespace JIT.HardwareIntrinsics.Arm ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); } - public void RunSameLclVarScenario_UnsafeRead() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunSameLclVarScenario_UnsafeRead)); - - var op = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr); - var op1 = op; - var op2 = op; - var op3 = op; - var result = {Isa}.{Method}(op1, op2, op3); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(op1, op2, op3, _dataTable.outArrayPtr); - } - public void RunClassFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario)); @@ -307,16 +296,6 @@ namespace JIT.HardwareIntrinsics.Arm ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr); } - public void RunSameClassFldScenario() - { - TestLibrary.TestFramework.BeginScenario(nameof(RunSameClassFldScenario)); - - var result = {Isa}.{Method}(_fld1, _fld1, _fld1); - - Unsafe.Write(_dataTable.outArrayPtr, result); - ValidateResult(_fld1, _fld1, _fld1, _dataTable.outArrayPtr); - } - public void RunStructLclFldScenario() { TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario)); @@ -339,64 +318,64 @@ namespace JIT.HardwareIntrinsics.Arm public void ConditionalSelect_Op1() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _resultFld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _resultFld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld1); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op1_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld1); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld1); } public void ConditionalSelect_Op2() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _resultFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _resultFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld2); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op2_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld2); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld2); } public void ConditionalSelect_Op3() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _resultFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _resultFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _resultFld3); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_Op3_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _fld3); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _resultFld3); } public void ConditionalSelect_FalseOp() @@ -405,44 +384,44 @@ namespace JIT.HardwareIntrinsics.Arm ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_mask - operation in FalseValue"); ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, _falseFld); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_FalseOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, _falseFld); } public void ConditionalSelect_ZeroOp() { TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in TrueValue"); - ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in TrueValue"); - ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_mask - operation in FalseValue"); - ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue(_mask, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_zero - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.Zero, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); TestLibrary.TestFramework.BeginScenario("ConditionalSelect_ZeroOp_all - operation in FalseValue"); - ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{Op1BaseType}>.Zero); + ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}>.AllBitsSet, _fld1, _fld2, _fld3, {Op1VectorType}<{RetBaseType}>.Zero); } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{Op1BaseType}> falseOp) + private void ConditionalSelectScenario_TrueValue({Op1VectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{RetBaseType}> falseOp) { var result = Sve.ConditionalSelect(mask, {Isa}.{Method}(op1, op2, op3), falseOp); @@ -451,7 +430,7 @@ namespace JIT.HardwareIntrinsics.Arm } [method: MethodImpl(MethodImplOptions.AggressiveInlining)] - private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{Op1BaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{Op1BaseType}> trueOp) + private void ConditionalSelectScenario_FalseValue({Op1VectorType}<{RetBaseType}> mask, {Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, {Op1VectorType}<{RetBaseType}> trueOp) { var result = Sve.ConditionalSelect(mask, trueOp, {Isa}.{Method}(op1, op2, op3)); @@ -480,20 +459,20 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{Op1BaseType}> falseOp, void* output, [CallerMemberName] string method = "") + private void ValidateConditionalSelectResult_TrueValue({Op1VectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{RetBaseType}> falseOp, void* output, [CallerMemberName] string method = "") { - {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; {Op1BaseType}[] first = new {Op1BaseType}[Op1ElementCount]; {Op2BaseType}[] second = new {Op2BaseType}[Op2ElementCount]; {Op3BaseType}[] third = new {Op3BaseType}[Op3ElementCount]; - {Op1BaseType}[] falseVal = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] falseVal = new {RetBaseType}[RetElementCount]; {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref first[0]), firstOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref second[0]), secondOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref third[0]), thirdOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref falseVal[0]), falseOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref second[0]), secondOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref third[0]), thirdOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref falseVal[0]), falseOp); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); bool succeeded = true; @@ -515,20 +494,20 @@ namespace JIT.HardwareIntrinsics.Arm } } - private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{Op1BaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{Op1BaseType}> trueOp, void* output, [CallerMemberName] string method = "") + private void ValidateConditionalSelectResult_FalseValue({Op1VectorType}<{RetBaseType}> maskOp, {Op1VectorType}<{Op1BaseType}> firstOp, {Op1VectorType}<{Op2BaseType}> secondOp, {Op1VectorType}<{Op3BaseType}> thirdOp, {Op1VectorType}<{RetBaseType}> trueOp, void* output, [CallerMemberName] string method = "") { - {Op1BaseType}[] mask = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] mask = new {RetBaseType}[RetElementCount]; {Op1BaseType}[] first = new {Op1BaseType}[Op1ElementCount]; {Op2BaseType}[] second = new {Op2BaseType}[Op2ElementCount]; {Op3BaseType}[] third = new {Op3BaseType}[Op3ElementCount]; - {Op1BaseType}[] trueVal = new {Op1BaseType}[Op1ElementCount]; + {RetBaseType}[] trueVal = new {RetBaseType}[RetElementCount]; {RetBaseType}[] result = new {RetBaseType}[RetElementCount]; - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref mask[0]), maskOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref mask[0]), maskOp); Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref first[0]), firstOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref second[0]), secondOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref third[0]), thirdOp); - Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref trueVal[0]), trueOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref second[0]), secondOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref third[0]), thirdOp); + Unsafe.WriteUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref trueVal[0]), trueOp); Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref result[0]), ref Unsafe.AsRef(output), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>()); bool succeeded = true; @@ -553,8 +532,8 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op1VectorType}<{Op2BaseType}> op2, {Op1VectorType}<{Op3BaseType}> op3, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op1ElementCount]; - {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1); @@ -568,8 +547,8 @@ namespace JIT.HardwareIntrinsics.Arm private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "") { {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount]; - {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op1ElementCount]; - {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op1ElementCount]; + {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount]; + {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount]; {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount]; Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>()); diff --git a/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.cs b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.cs new file mode 100644 index 00000000000..7ca27eb30a3 --- /dev/null +++ b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// Failure calling a synchronized method in an assembly loaded in a collectible AssemblyLoadContext: +// +// Unhandled exception. System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. +// ---> System.NullReferenceException: Object reference not set to an instance of an object. +// at System.RuntimeTypeHandle.GetRuntimeTypeFromHandle(IntPtr handle) +// at Runtime_117566.Synchronized() +// at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(System.Object, IntPtr*) +// at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(System.Object, System.Reflection.BindingFlags) +// at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Globalization.CultureInfo) +// at System.Reflection.MethodBase.Invoke(System.Object, System.Object[]) +// at Runtime_117566.TestEntryPoint() + +using System.Reflection; +using System.Runtime.Loader; +using System.Runtime.CompilerServices; +using Xunit; + +public class Runtime_117566 +{ + [Fact] + public static void TestEntryPoint() + { + var context = new AssemblyLoadContext("CollectibleALC", isCollectible: true); + Assembly assembly = context.LoadFromAssemblyPath(Assembly.GetExecutingAssembly().Location); + + var method = assembly.GetType(nameof(Runtime_117566)).GetMethod(nameof(Synchronized), BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); + method?.Invoke(null, []); + } + + [MethodImpl(MethodImplOptions.Synchronized)] + internal static void Synchronized() + { } +} diff --git a/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.csproj b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.csproj new file mode 100644 index 00000000000..1c287f51f44 --- /dev/null +++ b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117566/Runtime_117566.csproj @@ -0,0 +1,10 @@ + + + True + + true + + + + + diff --git a/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.cs b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.cs new file mode 100644 index 00000000000..9a91aaf7a75 --- /dev/null +++ b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.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. + +// Generated by Fuzzlyn v3.3 on 2025-07-14 11:26:52 +// Run on X64 Windows +// Seed: 5654087083843205658-vectort,vector128,vector256,x86aes,x86avx,x86avx2,x86avx512bw,x86avx512bwvl,x86avx512cd,x86avx512cdvl,x86avx512dq,x86avx512dqvl,x86avx512f,x86avx512fvl,x86avx512fx64,x86bmi1,x86bmi1x64,x86bmi2,x86bmi2x64,x86fma,x86lzcnt,x86lzcntx64,x86pclmulqdq,x86popcnt,x86popcntx64,x86sse,x86ssex64,x86sse2,x86sse2x64,x86sse3,x86sse41,x86sse41x64,x86sse42,x86sse42x64,x86ssse3,x86x86base +// Reduced from 33.4 KiB to 0.9 KiB in 00:01:30 +// Hits JIT assert for Release: +// Assertion failed '(maskBaseSize == 4) || (maskBaseSize == 8)' in 'Program:M0()' during 'Rationalize IR' (IL size 87; hash 0xaf50ff37; FullOpts) +// +// File: D:\a\_work\1\s\src\coreclr\jit\gentree.cpp Line: 20819 +// + +using System.Numerics; +using System.Runtime.Intrinsics; +using System.Runtime.Intrinsics.X86; +using Xunit; + +public class Runtime_117605 +{ + static Vector[] s_2; + + [Fact] + public static void TestEntryPoint() + { + if (Avx2.IsSupported) + { + M0(); + } + } + + private static void M0() + { + var vr3 = Vector256.Create(0, 7424648407429701945UL, 0, 0); + var vr6 = Vector256.Create(0); + var vr7 = Vector128.CreateScalar(9831122154695836571UL); + var vr4 = Avx2.InsertVector128(vr6, vr7, 0); + var vr8 = Vector256.CreateScalar(1497050855019840058UL); + var vr2 = Avx2.BlendVariable(vr3, vr4, vr8); + C0 vr9 = new C0(); + var vr1 = vr9.M3(ref s_2, vr2); + } + + class C0 + { + public short M3(ref Vector[] arg0, Vector256 arg1) + { + var vr5 = Vector128.Create(0, -1, 0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0); + return (short)Sse2.MoveMask(vr5); + } + } +} diff --git a/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.csproj b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.csproj new file mode 100644 index 00000000000..de6d5e08882 --- /dev/null +++ b/src/runtime/src/tests/JIT/Regression/JitBlue/Runtime_117605/Runtime_117605.csproj @@ -0,0 +1,8 @@ + + + True + + + + + diff --git a/src/runtime/src/tests/JIT/interpreter/Interpreter.cs b/src/runtime/src/tests/JIT/interpreter/Interpreter.cs index 61c02d4bb61..90516f0466a 100644 --- a/src/runtime/src/tests/JIT/interpreter/Interpreter.cs +++ b/src/runtime/src/tests/JIT/interpreter/Interpreter.cs @@ -2075,6 +2075,11 @@ public static T TestUnboxInst(object o) struct GenericStruct { public T Value; + + public override string ToString() + { + return "GenericStruct: " + (Value?.ToString() ?? ""); + } } public static int preciseInitCctorsRun = 0; diff --git a/src/runtime/src/tests/build.proj b/src/runtime/src/tests/build.proj index 8499575b01c..b1fd5ba3b72 100644 --- a/src/runtime/src/tests/build.proj +++ b/src/runtime/src/tests/build.proj @@ -264,6 +264,7 @@ AppDir="$(BuildDir)" DiagnosticPorts="$(DiagnosticPorts)" ForceInterpreter="$(MonoInterp)" + InvariantGlobalization="$(InvariantGlobalization)" RuntimeHeaders="$(MicrosoftNetCoreAppRuntimePackDir)/native/include/mono-2.0" OutputDir="$(AppDir)" ProjectName="$(Category)" diff --git a/src/source-manifest.json b/src/source-manifest.json index bfbb343af61..a3c409331c0 100644 --- a/src/source-manifest.json +++ b/src/source-manifest.json @@ -37,10 +37,10 @@ "commitSha": "15863918a40fc31d0498ca5f1b8a5f7f7ada113a" }, { - "barId": 275325, + "barId": 275390, "path": "efcore", "remoteUri": "https://github.com/dotnet/efcore", - "commitSha": "bc5def338228c7ec5ab5d46f6e9042439270f438" + "commitSha": "74068d2036ea9db2454d62865eef3a1414622538" }, { "barId": 274251, @@ -55,10 +55,10 @@ "commitSha": "4afdc9ffe3543c8fbd2b0b1271624a965bf7f48e" }, { - "barId": 274806, + "barId": 275447, "path": "msbuild", "remoteUri": "https://github.com/dotnet/msbuild", - "commitSha": "f51a5b98ca1efd516dcfdedf23153dfa03a1014d" + "commitSha": "5d215b0562b3de52781d0bd518805e464790290d" }, { "barId": 271771, @@ -73,10 +73,10 @@ "commitSha": "88d10f21004784390b5e220607bd4fa6ebfe1301" }, { - "barId": 275167, + "barId": 275529, "path": "roslyn", "remoteUri": "https://github.com/dotnet/roslyn", - "commitSha": "c1794aa58db74f27cd6bc7afc1b1d72b713f393b" + "commitSha": "462275d9e4c56b6fa2c4e1616f7dd2251f3a3ef7" }, { "barId": 273951, @@ -85,10 +85,10 @@ "commitSha": "714a51c57430dab50b67e5b468016288f5f7b0bd" }, { - "barId": 275332, + "barId": 275521, "path": "runtime", "remoteUri": "https://github.com/dotnet/runtime", - "commitSha": "6d7ba3656fa078fb17e68b4e31dc9fd9ff9868da" + "commitSha": "af05ae4672443e875e5b7768cb71bbbfaa351674" }, { "barId": 273704, @@ -139,16 +139,16 @@ "commitSha": "7890fbb7f086ae12b11ca85499b18f460c9090dd" }, { - "barId": 275281, + "barId": 275490, "path": "winforms", "remoteUri": "https://github.com/dotnet/winforms", - "commitSha": "6dd129e422c9b14dc835e669688247386bef2f95" + "commitSha": "c9252f63c0bfc3ad70278583bfd84963414acd04" }, { - "barId": 275192, + "barId": 275380, "path": "wpf", "remoteUri": "https://github.com/dotnet/wpf", - "commitSha": "900946a8e06533fd7ea8909d91b0c879a7c1f9be" + "commitSha": "0567cc262408546036a3f57b1d60d42eb083e5df" }, { "barId": 274010, diff --git a/src/winforms/eng/Version.Details.xml b/src/winforms/eng/Version.Details.xml index b6532e2949e..3c33d9e7d32 100644 --- a/src/winforms/eng/Version.Details.xml +++ b/src/winforms/eng/Version.Details.xml @@ -6,106 +6,106 @@ Note: if the Uri is a new place, you will need to add a subscription from that p And you can check these with "darc get-dependencies target-repo "winforms" --> - + - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 3c34a3f0178f5a637d21c3f0ba5a4ee86ab8e976 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b diff --git a/src/winforms/eng/Versions.props b/src/winforms/eng/Versions.props index 215d3204b77..80e925eee2e 100644 --- a/src/winforms/eng/Versions.props +++ b/src/winforms/eng/Versions.props @@ -10,30 +10,30 @@ $(MajorVersion).$(MinorVersion).$(PatchVersion) false release - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 5.0.0-preview.7.20320.5 - 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25365.101 6.1.0-preview.1.24511.1 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 10.0.0-preview.5.25227.101 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 - 10.0.0-preview.7.25364.102 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 @@ -46,9 +46,9 @@ - 10.0.0-beta.25364.102 - 10.0.0-beta.25364.102 - 10.0.0-beta.25364.102 + 10.0.0-beta.25365.101 + 10.0.0-beta.25365.101 + 10.0.0-beta.25365.101 17.4.0-preview-20220707-01 diff --git a/src/winforms/global.json b/src/winforms/global.json index a274e977be5..5b9af45917a 100644 --- a/src/winforms/global.json +++ b/src/winforms/global.json @@ -21,11 +21,11 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25364.102", - "Microsoft.DotNet.CMake.Sdk": "10.0.0-beta.25364.102", - "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25364.102", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25365.101", + "Microsoft.DotNet.CMake.Sdk": "10.0.0-beta.25365.101", + "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25365.101", "FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0", - "Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25364.102" + "Microsoft.NET.Sdk.IL": "10.0.0-preview.7.25365.101" }, "native-tools": { "cmake": "latest" diff --git a/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/ButtonDarkModeRendererBase.cs b/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/ButtonDarkModeRendererBase.cs index 955e8195f7a..413b804020e 100644 --- a/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/ButtonDarkModeRendererBase.cs +++ b/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Controls/Buttons/ButtonInternal/DarkMode/ButtonDarkModeRendererBase.cs @@ -44,39 +44,37 @@ public void RenderButton( ArgumentNullException.ThrowIfNull(paintImage); ArgumentNullException.ThrowIfNull(paintField); - // Clear the background over the whole button area. - ClearBackground(graphics, parentBackgroundColor); - - // Use padding from ButtonDarkModeRenderer - Padding padding = PaddingCore; - - Rectangle paddedBounds = new( - x: bounds.X + padding.Left, - y: bounds.Y + padding.Top, - width: bounds.Width - padding.Horizontal, - height: bounds.Height - padding.Vertical); - - // Draw button background and get content bounds - Rectangle contentBounds = DrawButtonBackground(graphics, paddedBounds, state, isDefault); - - // Offset content bounds for Popup style when button is pressed - // if (flatStyle == FlatStyle.Popup && state == PushButtonState.Pressed) - // { - // contentBounds.Offset(1, 1); - // } - - // Paint image and field using the provided delegates - paintImage(contentBounds); - - paintField( - contentBounds, - GetTextColor(state, isDefault), - false); - - if (focused && showFocusCues) + // Scope the graphics state so all changes are reverted after rendering + using (new GraphicsStateScope(graphics)) { - // Draw focus indicator for other styles - DrawFocusIndicator(graphics, bounds, isDefault); + // Clear the background over the whole button area. + ClearBackground(graphics, parentBackgroundColor); + + // Use padding from ButtonDarkModeRenderer + Padding padding = PaddingCore; + + Rectangle paddedBounds = new( + x: bounds.X + padding.Left, + y: bounds.Y + padding.Top, + width: bounds.Width - padding.Horizontal, + height: bounds.Height - padding.Vertical); + + // Draw button background and get content bounds + Rectangle contentBounds = DrawButtonBackground(graphics, paddedBounds, state, isDefault); + + // Paint image and field using the provided delegates + paintImage(contentBounds); + + paintField( + contentBounds, + GetTextColor(state, isDefault), + false); + + if (focused && showFocusCues) + { + // Draw focus indicator for other styles + DrawFocusIndicator(graphics, bounds, isDefault); + } } } diff --git a/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Form.cs b/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Form.cs index 5c2f4d1fcfe..ce377646508 100644 --- a/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Form.cs +++ b/src/winforms/src/System.Windows.Forms/System/Windows/Forms/Form.cs @@ -1790,6 +1790,9 @@ private void ResetFormScreenCaptureMode() => private void SetScreenCaptureModeInternal(ScreenCaptureMode value) { + // Always reset to NONE before setting new affinity. + PInvoke.SetWindowDisplayAffinity(HWND, WINDOW_DISPLAY_AFFINITY.WDA_NONE); + WINDOW_DISPLAY_AFFINITY affinity = value switch { ScreenCaptureMode.Allow => WINDOW_DISPLAY_AFFINITY.WDA_NONE, @@ -4228,6 +4231,11 @@ protected override void OnHandleCreated(EventArgs e) { SetFormTitleProperties(); } + + if (FormScreenCaptureMode != ScreenCaptureMode.Allow) + { + SetScreenCaptureModeInternal(FormScreenCaptureMode); + } } /// diff --git a/src/wpf/eng/Version.Details.xml b/src/wpf/eng/Version.Details.xml index f77ebd9f51c..583716f628c 100644 --- a/src/wpf/eng/Version.Details.xml +++ b/src/wpf/eng/Version.Details.xml @@ -1,104 +1,104 @@ - + - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b https://dev.azure.com/dnceng/internal/_git/dotnet-wpf-int 8a6c1d81657ef04c040f598cafacf8f5a33abda2 - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b - + https://github.com/dotnet/dotnet - 0b032b9f942c1ae8de535a434c4f4a9206fd3339 + 78061f4bcc414fa2054be6237b1fd3813d8edf6b diff --git a/src/wpf/eng/Versions.props b/src/wpf/eng/Versions.props index c9a4bc5c364..165eb582b5d 100644 --- a/src/wpf/eng/Versions.props +++ b/src/wpf/eng/Versions.props @@ -19,33 +19,33 @@ dotnet/winforms is handling versions for the analyzers. --> $(MajorVersion).$(MinorVersion).0.0 - 10.0.0-beta.25363.101 - 10.0.0-beta.25363.101 - 10.0.0-beta.25363.101 + 10.0.0-beta.25365.101 + 10.0.0-beta.25365.101 + 10.0.0-beta.25365.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 4.6.0-preview4.19176.11 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 - 10.0.0-preview.7.25363.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 + 10.0.0-preview.7.25365.101 @@ -59,7 +59,7 @@ 9.0.0-beta.24053.1 - 10.0.0-beta.25363.101 + 10.0.0-beta.25365.101 diff --git a/src/wpf/global.json b/src/wpf/global.json index b479d6ad314..d17d95e8957 100644 --- a/src/wpf/global.json +++ b/src/wpf/global.json @@ -24,8 +24,8 @@ } }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25363.101", - "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25363.101", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.25365.101", + "Microsoft.DotNet.Helix.Sdk": "10.0.0-beta.25365.101", "Microsoft.Build.NoTargets": "3.7.56" }, "native-tools": { diff --git a/src/wpf/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ja.xlf b/src/wpf/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ja.xlf index 08915578b59..d2cc8991279 100644 --- a/src/wpf/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ja.xlf +++ b/src/wpf/src/Microsoft.DotNet.Wpf/src/PresentationFramework/Resources/xlf/Strings.ja.xlf @@ -4805,7 +4805,7 @@ Do you want to replace it? Top - - + pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy